2012-02-14 94 views
56
A = os.path.join(os.path.dirname(__file__), '..') 

B = os.path.dirname(os.path.realpath(__file__)) 

C = os.path.abspath(os.path.dirname(__file__)) 

我通常只是用實際路徑硬連線。但是這些語句在運行時決定路徑是有原因的,我真的很想理解os.path模塊,所以我可以開始使用它。__file__變量意味着什麼?

+5

很顯然,這不是一個通配符。 – tripleee 2012-02-14 04:59:51

+3

它是一個「魔術」變量;通配符意味着完全不同的東西。 – 2012-02-14 05:47:03

回答

66

當在Python中加載模塊時,__file__被設置爲其名稱。然後,您可以使用其他的功能找到該文件所在的目錄

以你的例子一次一個:

A = os.path.join(os.path.dirname(__file__), '..') 
# A is the parent directory of the directory where program resides. 

B = os.path.dirname(os.path.realpath(__file__)) 
# B is the canonicalised (?) directory where the program resides. 

C = os.path.abspath(os.path.dirname(__file__)) 
# C is the absolute path of the directory where the program resides. 

你可以看到這些人,返回的各種值:

import os 
print __file__ 
print os.path.join(os.path.dirname(__file__), '..') 
print os.path.dirname(os.path.realpath(__file__)) 
print os.path.abspath(os.path.dirname(__file__)) 

,並確保你從不同的地點(如./text.py~/python/text.py等)運行地看到,能起到什麼作用。

+3

很好的答案,但請參閱其他答案的其他重要細節:'__file__'並未在所有情況下定義,例如靜態鏈接的C模塊。我們不能指望'__file__'始終可用。 – 2014-02-18 15:46:56

+2

在解釋器中,所有示例都返回'name'__file__'未定義。 – user1063287 2014-11-25 22:51:09

+2

@ user1063287看DemoUser的答案; '__file__'是從模塊加載的文件的路徑名,如果它是從文件加載的。這意味着'__file__'只有在你作爲腳本不在解釋器中運行時纔會起作用(除非你在解釋器中導入它) – YOUNG 2015-07-14 00:48:18

10

documentation

__file__是文件的路徑名,從該模塊是 加載,如果它是從一個文件裝載。對於靜態鏈接到解釋器的C模塊,__file__屬性不是 ; 對於從共享庫動態加載的擴展模塊,共享庫文件的路徑名是 。

also和:

__file__是成爲「路徑」在這種情況下,屬性未設置,除非該模塊被內置(並因此列入sys.builtin_module_names)該文件。

8

使用__file__與各種os.path模塊相結合允許所有路徑是相對的當前模塊的目錄位置。這使您的模塊/項目可以移植到其他機器上。

在你的項目你做:

A = '/Users/myname/Projects/mydevproject/somefile.txt' 

,然後嘗試將其與像/home/web/mydevproject/一個部署目錄部署到服務器,然後你的代碼將無法正確找到路徑。

30

我只想先解決一些困惑。 __file__不是通配符,它​​是一個屬性。雙下劃線的屬性和方法被認爲是「特殊」的約定和服務於特殊目的。

http://docs.python.org/reference/datamodel.html顯示了許多特殊的方法和屬性,如果不是全部的話。

在這種情況下,__file__是模塊(模塊對象)的屬性。在Python中,.py文件是一個模塊。因此import amodule將具有__file__的屬性,這意味着在不同情況下的不同事情。

從文檔摘自:

__file__是從哪個模塊的加載,如果它是從文件加載的文件的路徑名。對於靜態鏈接到解釋器中的C模塊,__file__屬性不存在 ;對於從共享庫中動態加載的 擴展模塊,它是共享庫文件的路徑名 。

在你的情況下,模塊正在全局命名空間中訪問它自己的__file__屬性。

要看到這個動作的嘗試:

# file: test.py 

print globals() 
print __file__ 

並運行:

python test.py 

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__file__': 
'test_print__file__.py', '__doc__': None, '__package__': None} 
test_print__file__.py