在代码仓库中如何引用资源的相对路径

220 投票
10 回答
237499 浏览
提问于 2025-04-15 13:34

我们正在处理一个代码库,这个代码库同时在Windows和Linux上运行,有时候它们的文件夹位置还不一样。那么,项目里面的一个模块应该怎么引用项目中的一些非Python资源,比如CSV文件呢?

如果我们这样做:

thefile = open('test.csv')

或者:

thefile = open('../somedirectory/test.csv')

这样的话,脚本只能在某个特定的文件夹下运行,或者只能在一些特定的文件夹下运行。

我想要做的是这样的:

path = getBasePathOfProject() + '/somedirectory/test.csv'
thefile = open(path)

这样可行吗?

10 个回答

22

在Python中,路径是相对于当前工作目录的。通常来说,当前工作目录就是你运行程序时所在的文件夹。需要注意的是,当前工作目录很可能和你的模块文件所在的文件夹不一样,所以用相对于模块文件的路径通常不是个好主意。

使用绝对路径应该是最好的解决办法:

import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')
52

如果你在使用安装工具,比如setup tools或者distribute(也就是用setup.py来安装),那么访问这些打包资源的“正确”方式是使用package_resources。

在你的例子中,可以这样做:

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")

这样做会读取资源,读取到的二进制数据就是my_data的值。

如果你只需要文件名,也可以使用:

resource_filename(package_or_requirement, resource_name)

举个例子:

resource_filename("MyPackage","foo.dat")

这样做的好处是,即使是像egg这样的压缩包分发方式,它也能保证正常工作。

更多信息可以查看这个链接:http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api

298

试着使用一个相对于当前文件路径的文件名。比如说 './my_file':

fn = os.path.join(os.path.dirname(__file__), 'my_file')

在 Python 3.4 及以上版本中,你还可以使用 pathlib 这个库:

fn = pathlib.Path(__file__).parent / 'my_file'

撰写回答