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

Python 使用代码存储库时如何引用资源的相对路径,python,path,relative-path,Python,Path,Relative Path,我们正在使用一个部署到Windows和Linux的代码库,有时部署在不同的目录中。项目中的一个模块应该如何引用项目中的一个非Python资源(CSV文件等) 如果我们这样做: thefile=open('test.csv') path=getBasePathOfProject()+'/somedirectory/test.csv' thefile=open(path) 或: 仅当脚本从一个特定目录或目录的子集运行时,它才起作用 我想做的是: thefile=open('test.csv')

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

如果我们这样做:

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

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

我想做的是:

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

是否可能?

尝试使用相对于当前文件路径的文件名。“/my_文件”的示例:

fn = os.path.join(os.path.dirname(__file__), 'my_file')
在Python 3.4+中,您还可以使用:


您可以使用内置的
\uuuuu文件
变量。它包含当前文件的路径。我将在项目根目录中的模块中实现getBaseOfProject。在那里,我将获得
\uuuu文件的路径部分并返回该部分。这种方法可以在项目中的任何地方使用

import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)

您还尝试使用
os.path.abspath(os.getcwd())
规范化
cwd
。更多信息。

我经常使用类似的方法:

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))
    # ...
变量

__file__
保存您在其中编写代码的脚本的文件名,因此您可以创建相对于脚本的路径,但仍然使用绝对路径编写。由于以下几个原因,它工作得相当好:

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

但您需要注意平台兼容性—Windows的os.pathsep与UNIX不同。

我花了很长时间才找到了答案,但我终于找到了答案(其实很简单):

这将把子文件夹的相对路径附加到python要查找的目录中
它非常快而且脏,但它的工作方式很有魅力:)

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

在你的情况下,这个例子是

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")
当然,读取资源和读取的二进制数据将是my_数据的值

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

resource_filename(package_or_requirement, resource_name)
例如:

resource_filename("MyPackage","foo.dat")
其优点是,即使它是一个像鸡蛋一样的归档发行版,它也能保证正常工作


请参见Python中的

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

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

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

我在这里被难住了。想要将一些资源文件打包成一个轮子文件并访问它们。使用manifest文件进行打包,但是pip install没有安装它,除非它是一个子目录。希望这些照片能有所帮助

├── cnn_client
│   ├── image_preprocessor.py
│   ├── __init__.py
│   ├── resources
│   │   ├── mscoco_complete_label_map.pbtxt
│   │   ├── retinanet_complete_label_map.pbtxt
│   │   └── retinanet_label_map.py
│   ├── tf_client.py
舱单

recursive-include cnn_client/resources *
使用standard setup.py创建了一个weel。pip安装了车轮锉刀。 安装后,检查是否安装了资源。是的

ls /usr/local/lib/python2.7/dist-packages/cnn_client/resources

mscoco_complete_label_map.pbtxt
retinanet_complete_label_map.pbtxt 
 retinanet_label_map.py  
在tfclient.py中访问这些文件


它是有效的。

我认为只有当资源位于python文件的同一目录或其子目录中时,此解决方案才有效。当您有以下树结构时,您如何解决它:/Project\u Root\u dir/python\u files\u dir/这里的一些子目录py\u file.py/resources/这里的一些子目录resource\u file.csvSorry,文件树在最后一条消息中被弄乱了。。。第二次尝试:您的文件位于/Project\u Root\u dir/python\u files\u dir/some\u subdirs/py\u file.py,您的资源文件位于/Project\u Root\u dir/resources/some\u subdirs/resource\u file.csv您应该能够使用join(foo,“…”)访问父目录。因此,在/root/python_files/module/myfile中,使用os.path.join(os.path.dirname(
________
)、“…”、“…”、“…”、“…”、“resources”)略优于
,尽管两者在POSIX和Windows上都是等效的。@cedbeu:它在我遇到的每个系统上都是等效的,我认为今天python运行的每个系统都是等效的(如果我在这里错了,请纠正我)。但是,如果您希望python将来被移植到一个使用不同路径分隔符的系统,并且希望您的代码能够为它做好准备,那么os.pardir将更具可移植性。我认为,每一个程序员,即使是从未读过任何python的程序员,都知道“.”的含义,而“os.pardir”是一个间接级别,您必须在文档中查找,因此我个人坚持使用“.”。只有当您从与所讨论的.py文件相同的目录运行Python程序时,这才有效。在这种情况下,您可以执行
open('your/subfolder/of/choice'))
无论如何。OP提到代码需要在Windows和Linux上工作。这不会。很少有使用案例中,
cwd
是模块的路径,尽管它不在包内工作,只是来自同一目录(或工作目录)由脚本设置。如果用户使用来自不同目录的绝对路径运行程序,这将不起作用。例如,python3/usr/someone/test.py我知道这是一个旧答案,我首选的方法是(/was-maybe?)使用pkg_资源,但随着压缩鸡蛋的消失,像过去一样使用
\uuuu文件\uuuu
有什么害处吗?这是一个可靠的方法。即使鸡蛋约定正在消失,setuptools也没有,许多人仍然在运行时构建鸡蛋的git repos上安装dep
ls /usr/local/lib/python2.7/dist-packages/cnn_client/resources

mscoco_complete_label_map.pbtxt
retinanet_complete_label_map.pbtxt 
 retinanet_label_map.py  
templates_dir = os.path.join(os.path.dirname(__file__), 'resources')
 file_path = os.path.join(templates_dir, \
            'mscoco_complete_label_map.pbtxt')
        s = open(file_path, 'r').read()