【发布时间】:2020-08-19 02:14:16
【问题描述】:
我有一个项目需要从 python2 更新到 python3。它目前使用pkg_resources,它有很大的开销(PyCon 2018 - Get Your Resources Faster with importlib.resources, by Barry Warsaw)。它将被打包成一个 zip 文件。包结构的相关部分是:
+-- project/
|__+ __init__.py
|__+ main.py
|__resources/
| |__+ images/
| | |__ # program images
| |__+ logging/
| |__+ custom_logger.py
|__log/
|__+ project_log.log
原始问题的意图
最初问题的目的是询问“如何从另一个子包中获取子包的绝对路径”,但我在措辞上做得很差。我认为由于current working directory 的意思是“运行cwd 命令的路径”,所以可以使用它,但后来我了解到我的理解是不完整的。 current working directory 表示(用外行的话)“从在命令行 运行cwd 命令的路径”)。这就是我遇到麻烦的原因。如果我从顶级包中运行我的程序
C:\Users\usr\Destop\program>py main.py
并在任何其他子包(resources、logging、log)中的.py 文件中使用pathlib.Path.cwd(),我会得到相同的答案:
C:\Users\usr\Destop\program
我了解到这是正确的行为,但这意味着我不能使用相对路径从一个子包到另一个子包(我需要使用相对路径,因为我不知道最终用户将在他/她的哪里安装此程序机器)。
与未明确说明的问题相关的第二部分
由于我的部分需求是更新到 python3,因此对 pkgutil 和 importlib.resources 进行了调查。其中每一个都需要将资源视为包,因此要更新以使用其中任何一个,我必须将__init__.py 添加到文件夹resources、logging 和log。谢天谢地,这没什么大不了的,因为这不是一个大型程序。
请注意,为了向后兼容最少的代码重新编辑,已建议其他人使用命名空间重命名(例如,请参阅 (How to use importlib.resources.path(package, resource)?)。:
try:
import importlib.resources as pkg_resources
except ImportError:
# Try backported to PY<37 `importlib_resources`.
import importlib_resources as pkg_resources
pgkutil 和 importlib.resources 都没有直接返回“这个子包”的方法(就像pathlib.Path.cwd()“直接返回”cwd 没有任何额外的代码),但我认为importlib.resources 有一种我可以使用的方法,它需要最少的代码并且读者仍然可以理解。请注意,要求是获取“此子包”的绝对路径,仅此而已。我不想使用不同的方法。
我会使用的方法是
try:
import importlib.resources as pkg_resources
except ImportError:
# Try backported to PY<37 `importlib_resources`.
import importlib_resources as pkg_resources
with pkg_resources.path("logging", "__init__.py") as fl:
path = fl.parent.resolve()
结论
除此之外,我没有任何问题,因为它可能会被判断为“意见”问题。请注意 __file__ 方法是不可接受的,因为这不适用于 zip 包(请参阅 PyCon 2018 - Get Your Resources Faster with importlib.resources, by Barry Warsaw)。如果这种方法有什么不正确或者可以改进的地方,我想知道。
【问题讨论】:
-
在这两种情况下,您都希望答案是“项目”吗?我认为这可能需要了解目录结构的嵌套程度。
-
@mk03 我对你的意思感到困惑。你是在谈论
Path.cwd()返回的内容吗? -
我想问你想要的输出是什么?
-
所需的输出将是文件的绝对路径。为此,我可能需要更改为
cwd = str(fl.parent.resolve())。
标签: python-3.7 working-directory pathlib python-importlib