Python包中的相对文件路径

20 投票
4 回答
19018 浏览
提问于 2025-04-15 12:19

我该如何相对引用一个文件到一个包的目录呢?

我的目录结构是:

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

script.py 导入了 package1package2 这两个包。虽然这些包可以被系统上任何其他脚本导入。那么,我应该如何引用里面的资源,比如 package1,以确保在 os.path.curdir 是任意的情况下也能正常工作呢?

4 个回答

4

如果你想在使用方便的接口的同时确保你的代码可以在压缩包中安全运行,可以使用 twisted.python.modules

举个例子,假设我有一个名为 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;如果它在一个压缩文件里,得到的就是一个 ZipPath,这个路径支持大部分,但不是全部,和 FilePath 一样的功能。

14

一个简单又安全的方法是使用来自 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')

这样做能给你一个干净的解决方案,而且(如果我没记错的话)是可以在压缩包中安全使用的。

27

如果你想引用来自 foo/package1/resources 文件夹的文件,你可以使用模块的 __file__ 变量。在 foo/package1/__init__.py 文件里面,你可以这样做:

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

撰写回答