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

2025-02-27 09:06:00
admin
原创
75
摘要:问题描述:我们正在使用一个代码存储库,该存储库部署到 Windows 和 Linux - 有时位于不同的目录中。项目内的模块之一应如何引用项目中的非 Python 资源之一(CSV 文件等)?如果我们做类似的事情:thefile = open('test.csv') 或者:thefile = open('.....

问题描述:

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

如果我们做类似的事情:

thefile = open('test.csv')

或者:

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

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

我想做的是这样的:

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

是否可以?


解决方案 1:

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

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

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

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

解决方案 2:

如果您正在使用安装工具或分发(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

解决方案 3:

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

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

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

解决方案 4:

我经常使用类似这样的东西:

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 不同。

解决方案 5:

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

您还尝试规范化您的cwd使用os.path.abspath(os.getcwd())。更多信息请点击此处。

解决方案 6:

您可以使用内置变量__file__。它包含当前文件的路径。我将在项目根目录中的模块中实现 getBaseOfProject。在那里我将获取路径部分__file__并返回它。然后可以在项目中的任何地方使用此方法。

解决方案 7:

我在这里有点困惑。想将一些资源文件打包成一个 wheel 文件并访问它们。使用清单文件进行了打包,但 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 *

使用标准 setup.py 创建了一个 wheel。pip 安装了 wheel 文件。安装后检查资源是否已安装。它们是

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, \n            'mscoco_complete_label_map.pbtxt')
        s = open(file_path, 'r').read()

并且它有效。

解决方案 8:

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

以前,这个问题是用pkg_resourcesfrom处理的setuptools,但随着越来越多的工具出现,生态系统发生了变化。从 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有等效的方法。setuptools主页上提供了更完整的说明setup.py`pyproject.toml`

解决方案 9:

如果您希望稍后将脚本编译为 .exe,__file__不会为您提供 .exe 文件的路径。在这种情况下,您应该

使用sys.argv[0]

sys.argv[0]当文件为 .exe 并且您运行脚本时,会给出文件的路径python script.py

这就是我目前引用事物的方式

os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), 'Resources')

这里有更多关于为什么会发生这种情况的详细信息

解决方案 10:

我花了很长时间才找到这个问题的答案,但我终于明白了(其实它真的很简单):

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 要查找的目录中。这非常快捷且粗糙,但效果很好:)

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2974  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1836  
  PLM(产品生命周期管理)系统在企业的产品研发、生产与管理过程中扮演着至关重要的角色。然而,在实际运行中,资源冲突是经常会遇到的难题。资源冲突可能导致项目进度延迟、成本增加以及产品质量下降等一系列问题,严重影响企业的效益与竞争力。因此,如何有效应对PLM系统中的资源冲突,成为众多企业关注的焦点。接下来,我们将详细探讨5...
plm项目管理系统   47  
  敏捷项目管理与产品生命周期管理(PLM)的融合,正成为企业在复杂多变的市场环境中提升研发效率、增强竞争力的关键举措。随着技术的飞速发展和市场需求的快速更迭,传统的研发流程面临着诸多挑战,而将敏捷项目管理理念融入PLM,有望在2025年实现研发流程的深度优化,为企业创造更大的价值。理解敏捷项目管理与PLM的核心概念敏捷项...
plm项目   47  
  模块化设计在现代产品开发中扮演着至关重要的角色,它能够提升产品开发效率、降低成本、增强产品的可维护性与可扩展性。而产品生命周期管理(PLM)系统作为整合产品全生命周期信息的关键平台,对模块化设计有着强大的支持能力。随着技术的不断发展,到 2025 年,PLM 系统在支持模块化设计方面将有一系列令人瞩目的技术实践。数字化...
plm软件   48  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用