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

如果我们这样做:

thefile = open('test.csv')

or:

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

只有当脚本从一个特定目录或目录的一个子集运行时,它才会工作。

我想做的是:

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

这可能吗?


当前回答

你可以使用build in __file__变量。它包含当前文件的路径。我将在项目根的一个模块中实现getBaseOfProject。在那里,我将获得__file__的路径部分,并将返回它。然后可以在项目中的任何地方使用此方法。

其他回答

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

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

import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')
import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)

你也可以尝试使用os.path.abspath(os.getcwd())来规范化你的cwd。更多信息请点击这里。

我花了很长时间来思考这个问题的答案,但我最终得到了它(它实际上非常简单):

import sys
import os
sys.path.append(os.getcwd() + '/your/subfolder/of/choice')

# now import whatever other modules you want, both the standard ones,
# as the ones supplied in your subfolders

这将把子文件夹的相对路径附加到供python查找的目录中 它非常快速和肮脏,但它的工作就像一个魅力:)

我被难住了。想把一些资源文件打包到一个轮子文件中并访问它们。使用清单文件打包,但是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

MANIFEST.in

recursive-include cnn_client/resources *

使用标准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中访问这些文件。从

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()

这很有效。

既然你说你有一些代码要部署到不同的地方,你应该使用python生态系统来分发资源,而不仅仅局限于文件。它还支持访问zip归档中的文件,这可以很好,这样您就不必为此烦恼了。

以前,这是通过setuptools中的pkg_resources来处理的,但是随着越来越多的工具出现,生态系统已经发生了变化。从python 3.7开始,你应该使用importlib.resources

import importlib.resources
with importlib.resources.open_text('mypackage.somedirectory','text.csv') as f:
    print(f.read()) # or whatever

但是您还必须指示安装程序包含包资源。否则,pip install mypackage不会捆绑数据文件。

有很多方法可以做到这一点,但其中一种方法是添加

[options.package_data]
mypackage = 
    "somedirectory/*.csv"

进入你的setup.cfg。当使用setup.py或pyproject.toml时,有等效的方法。更完整的帐户可以在setuptools主页上找到