如何相对于包的目录引用文件?
我的目录结构是:
/foo 包1/ 资源/ __init__.py 包2/ 资源/ __init__.py 脚本.py
script.py
导入包package1
和package2
. 尽管可以通过系统上的任何其他脚本导入包。例如,我应该如何引用内部资源,package1
以确保它在os.path.curdir
任意情况下都能正常工作?
如何相对于包的目录引用文件?
我的目录结构是:
/foo 包1/ 资源/ __init__.py 包2/ 资源/ __init__.py 脚本.py
script.py
导入包package1
和package2
. 尽管可以通过系统上的任何其他脚本导入包。例如,我应该如何引用内部资源,package1
以确保它在os.path.curdir
任意情况下都能正常工作?
如果要从foo/package1/resources
文件夹中引用文件,则需要使用__file__
模块的变量。内部foo/package1/__init__.py
:
from os import path
resources_dir = path.join(path.dirname(__file__), 'resources')
一种简单/安全的方法是使用 pkg_resources 中的方法resource_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')
这为您提供了一个干净的解决方案,它也是(如果我没记错的话)拉链安全。
如果您使用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。
这是一个坏主意,因为如果您的软件包是作为 zipped egg 安装的,那么资源可能不可用。
如果您使用 setuptool,请不要忘记将 zip_safe=False 添加到 setup.py 配置中。