2009-06-18 217 views
12

如何引用文件相對於包的目錄?Python包中的相對文件路徑

我的目錄結構是:

 
    /foo 
    package1/ 
     resources/ 
     __init__.py 
    package2/ 
     resources/ 
     __init__.py 
    script.py 

script.py進口包package1package2。雖然軟件包可以通過系統上的任何其他腳本導入。我應該如何引用內部資源,例如package1以確保它可以在os.path.curdir是任意的情況下工作?

回答

14

如果您想引用foo/package1/resources文件夾中的文件,您希望使用模塊的__file__變量。內部foo/package1/__init__.py

from os import path 
resources_dir = path.join(path.dirname(__file__), 'resources') 
+0

正如另一個答案所指出的,如果您的應用程序打包在一個zip文件中,這將不起作用。 – Glyph 2009-06-18 08:35:59

0

這是一個壞主意,因爲如果你的包被安裝爲拉鍊雞蛋,那麼資源可能不可用。

如果您使用setuptool,請不要忘記將zip_safe = False添加到setup.py配置中。

+3

這是真的,但它確實應該是在評論而不是回答中,因爲它不回答問題。 – Glyph 2009-06-18 08:38:46

4

如果您使用twisted.python.modules,您可以使用zip安全且同時使用便利的API。

舉例來說,如果我有一個data.txt在一些文本和這sample.py在一個目錄:

from twisted.python.modules import getModule 
moduleDirectory = getModule(__name__).filePath.parent() 
print repr(moduleDirectory.child("data.txt").open().read()) 

然後導入sample會做到這一點:

>>> import sample 
'Hello, data!\n' 
>>> 

如果你的模塊在一個常規目錄中,getModule(__name__).filePath將是一個FilePath;如果它在一個zip文件中,它將是一個ZipPath,它支持大部分但不是全部的相同的API。

4

一個簡單/安全的方式做到這一點是使用從pkg_resourcesresource_filename方法(一起發行setuptools),像這樣:

from pkg_resources import resource_filename 
filepath = resource_filename('package1', 'resources/thefile') 

或者,如果你在裏面package1/___init___.py實現這一點:

from pkg_resources import resource_filename 
filepath = resource_filename(__name__, 'resources/thefile') 

這給你一個乾淨的解決方案,也是(如果我沒有錯誤)拉鍊安全。