如何从python脚本中获取资源文件的完整路径?



好的,所以我在包中做了一个python脚本。树看起来像这样:

├── foo
│   ├── __init__.py
│   ├── funcs
│   │   ├── __init__.py
│   │   └── stuff.py
│   ├── resources
│   │   └── haarcascade_frontalface_default.xml
│   └── scripts
│       ├── __init__.py
│       └── script.py
└── setup.py

因此,在脚本文件中,im使用 openCV 的 cv2 来检测人脸,为此cv2.CascadeClassifier需要位于/resources 下的 XML 文件的路径。现在,由于这是一个脚本,我需要能够从任何地方运行它,因此可悲的是,资源文件的相对路径无法解决问题。如何从 script.py 中获取 xml 文件的绝对路径?您可以假设脚本和 xml 文件分别相对位于彼此的位置,就像上面的示例一样。谢谢:)(

PS:如果解决方案也适用于鸡蛋,则奖金。非常感谢

目前最好的方法是importlib.resources.从 Python 3.7 开始,它在标准库中可用。对于早期版本,有一个名为importlib_resources的向后端口。

按照文档进行操作。

在您的情况下,这或多或少应该如下所示:

import importlib.resources
xml_path = importlib.resources.path('foo.resources', 'haarcascade_frontalface_default.xml')

这样做有很多优点,最重要的是它是标准的,即使它在zip文件中安装软件包,它也可以在任何地方工作。

在这种情况下,您可能需要__init__.py文件添加到resources目录中。

使用os模块有效,但如果您可以访问 python 版本>= 3.4,那么pathlib是一种替代方案,可以更轻松地处理自身并在跨平台上执行更好的性能:

from pathlib import Path
# when using pathlib.Path, slashes get automatically transformed into the 
# correct path-division character, depending on the platform
RESOURCES_PATH = Path(__file__).parent.parent / "resources"
face_cascade = cv2.CascadeClassifier()
face_cascade.load(RESOURCES_PATH / "haarcascade_frontalface_default.xml")

如果您发现自己定义了很多此类常量,请考虑将它们全部放在类似foo/util.py的文件中,以便它们在项目中轻松重用,并且不需要从脚本中重新声明或导入。


在 python>=3.7版本中更好的选择是使用importlib.resources.path,它从包根目录自动解析资源,因此您无需从__file__上走来手动查找它:

import importlib
face_cascade = cv2.CascadeClassifier()
with importlib.resources.path("foo.resources", "haarcascade_frontalface_default.xml") as haar_resource:
# haar_resource is a pathlib.Path object here as well, so plugging it is simple
face_cascade.load(haar_resource)

这要优雅得多,并且应该是首选解决方案,因为它是可用的。

我不确定我是否正确理解了这个问题,但也许os.path会有所帮助?像这样:

>>> import os
>>> os.path.abspath("directory/somefile.txt")
'C:/somedirectory/directory/directory/somefile.txt'

相关内容

  • 没有找到相关文章

最新更新