在Python中使用代码存储库时如何引用资源的相对路径

ola*_*ndo 179 python path relative-path

我们正在使用一个代码存储库,它部署在Windows和Linux上 - 有时在不同的目录上.项目中的一个模块应该如何引用项目中的一个非Python资源(CSV文件等)?

如果我们做类似的事情:

thefile=open('test.csv')
Run Code Online (Sandbox Code Playgroud)

要么:

thefile=open('../somedirectory/test.csv')
Run Code Online (Sandbox Code Playgroud)

仅当脚本从一个特定目录或目录的子集运行时,它才会起作用.

我想做的是:

path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)
Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?可能吗?

c08*_*089 240

尝试使用相对于当前文件路径的文件名.'./my_file'的示例:

fn = os.path.join(os.path.dirname(__file__), 'my_file')
Run Code Online (Sandbox Code Playgroud)

在Python 3.4+中,您还可以使用pathlib:

fn = pathlib.Path(__file__).parent / 'my_file'
Run Code Online (Sandbox Code Playgroud)

  • 您应该能够使用join(foo,'..')访问父目录.所以从/ root/python_files/module/myfile,使用os.path.join(os.path.dirname(`__ file__`),'..','..','resources') (27认同)
  • [`os.pardir`](http://docs.python.org/2/library/os.html#os.pardir)略好于''..'`,尽管两者在POSIX和视窗. (6认同)
  • @cedbeu:它相当于我遇到的每个系统,我认为每个系统python都在今天运行(如果我错了,请纠正我).但是,如果您希望将来使用不同的路径分隔符将python移植到系统并希望您的代码为它做好准备,那么os.pardir将更具可移植性.我会说每个程序员,甚至一个从未读过任何python的程序员都知道"..."的含义,而"os.pardir"是一个间接程度,我必须在文档中查找,所以我个人d坚持"......". (4认同)
  • 我认为只有当资源位于python文件的同一目录或其子目录中时,此解决方案才有效.如果你有以下树结构,你如何解决它:/ Project_Root_dir/python_files_dir /这里有一些更多的子目录py_file.py/resources/some subdirs here resource_file.csv (3认同)
  • 抱歉,文件树在最后一条消息中出现乱码...第二次尝试:您的文件位于 /Project_Root_dir/python_files_dir/some_subdirs/py_file.py ,您的资源文件位于 /Project_Root_dir/resources/some_subdirs/resource_file.csv (2认同)

Sha*_*mas 39

如果您正在使用安装工具或分发(setup.py安装),那么访问这些打包资源的"正确"方式似乎是使用package_resources.

在你的情况下,例子是

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")
Run Code Online (Sandbox Code Playgroud)

当然,读取资源和读取的二进制数据当然是my_data的值

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

resource_filename(package_or_requirement, resource_name)
Run Code Online (Sandbox Code Playgroud)

例:

resource_filename("MyPackage","foo.dat")
Run Code Online (Sandbox Code Playgroud)

优点是,即使它是像鸡蛋一样的存档分发,它也能保证工作.

请参阅http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api

  • 我知道这是一个古老的答案,我的首选方式是(/可能是?)使用pkg_resources,但是随着拉链蛋的消失,使用``__file__``就好像过去一样有害吗? (3认同)
  • 这是一个可靠的方法。即使 egg 约定消失了,setuptools 也没有,而且许多人仍在针对 git repos 安装 deps,其中 egg 是在运行时构建的 (2认同)

sky*_*ree 16

在Python中,路径是相对于当前工作目录的,在大多数情况下,这是您运行程序的目录.在当前的工作目录很可能不是同你的模块文件的目录,因此,使用相对于当前的模块文件的路径始终是一个不错的选择.

使用绝对路径应该是最佳解决方案:

import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')
Run Code Online (Sandbox Code Playgroud)


use*_*673 13

我经常使用类似的东西:

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir') 

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...
Run Code Online (Sandbox Code Playgroud)

变量

__file__
Run Code Online (Sandbox Code Playgroud)

保存您编写该代码的脚本的文件名,这样您就可以创建相对于脚本的路径,但仍然使用绝对路径编写.由于以下几个原因,它运作良好:

  • 路径是绝对的,但仍然是相对的
  • 该项目仍可部署在相关容器中

但是你需要注意平台兼容性 - Windows的os.pathsep与UNIX不同.


gav*_*oja 5

import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)
Run Code Online (Sandbox Code Playgroud)

您还尝试规范您的cwd使用os.path.abspath(os.getcwd()).更多信息在这里.

  • 但很少有用例,`cwd`是模块的路径 (2认同)