gpt4 book ai didi

python - 为什么使用 importlib.resources 而不是 __file__?

转载 作者:行者123 更新时间:2023-12-05 05:38:45 26 4
gpt4 key购买 nike

我有一个包是这样的

mypkg
|-mypkg
|- data
|- data.csv
|- __init__.py # Required for importlib.resources
|- scripts
|- module.py
|- __init__.py

模块 module.py 需要 data.csv 来执行特定任务。

我用来访问 data.csv 的第一个天真的方法是

# module.py - Approach 1
from pathlib import Path

data_path = Path(Path.cwd().parent, 'data', 'data.csv')

但是当我们通过 from mypkg.scripts import module 或类似方式导入 module.py 时,这显然会中断。我需要一种方法来访问 data.csv 而不管 mypkg 从哪里导入。

下一个简单的方法是使用 __file__ 属性来访问 module.py 模块所在的路径。

# module.py - Approach 2
from pathlib import Path

data_path = Path(Path(__file__).resolve().parents[1], 'data', 'data.csv')

但是,通过研究这个问题,我发现不鼓励使用这种方法。参见,例如,How to read a (static) file from inside a Python package? .

虽然似乎没有就此问题的最佳解决方案达成完全一致,但看起来 importlib.resources 可能是最受欢迎的。我相信这看起来像:

# module.py - Approach 3
from pathlib import Path
import importlib.resources

data_path_resource = importlib.resources('mypkg.data', 'data.csv')
with data_path_resources as resource:
data_path = resource

为什么这个 final方法比 __file__ 更好?如果源代码被压缩,似乎 __file__ 将不起作用。这是我不熟悉的情况,听起来也有点边缘。我认为我的代码永远不会压缩运行..

importlib 增加的开销似乎有点荒谬。我需要在数据文件夹中添加一个空的 __init__.py,我需要导入 importlib,我需要使用上下文管理器来访问相对路径。

关于 importlib 策略的好处,我错过了什么?为什么不直接使用 __file__

编辑:importlib 方法的一个可能的理由是它稍微改进了语义。那就是 data.csv 应该被认为是包的一部分,所以我们应该使用类似 from mypkg import data.csv 的东西来访问它,但当然这种语法只有效用于导入 .py python 模块。但是 importlib.resources 是将“从某个包中导入某些内容”语义移植到更通用的文件类型。

相比之下,从 __file__ 构建相对路径的语法有点像在说:这个模块在文件结构中偶然靠近数据文件,所以让我们利用它来访问它。数据文件是包的一部分这一事实没有得到利用。

最佳答案

你应该能够将类似这样的东西与 __file__ 一起使用:

import csv
from io import StringIO
from pathlib import Path
import pkgutil
import sys


def main():
# Point to appropriate ancestor directory
p = Path(__file__).parent.parent.parent
sys.path.insert(0, str(p))
data = pkgutil.get_data('mypkg.data', 'data.csv')
reader = csv.reader(StringIO(data.decode()))
for row in reader:
print(row)


if __name__ == '__main__':
main()

如果文件data.csv包含

Col 1,Col 2
v1,v2

然后上面的脚本会打印出来

['Col 1', 'Col 2']
['v1', 'v2']

你可以看到整个运行过程 here如果您选择“Shell”选项卡并运行 python mypkg/scripts/module.py

关于python - 为什么使用 importlib.resources 而不是 __file__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72886257/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com