尝试在 Python 包中读取 JSON 文件
Posted
技术标签:
【中文标题】尝试在 Python 包中读取 JSON 文件【英文标题】:Trying to read JSON file within a Python package 【发布时间】:2020-06-26 11:30:51 【问题描述】:我正在打包一个 python 包,我将其称为MyPackage
。
包结构为:
MyPackage/
script.py
data.json
data.json
文件包含在script.py
中读取的缓存数据。
我已经弄清楚如何包含数据文件(使用 setuptools include_package_data=True
并在 MANIFEST.in
文件中包含数据文件的路径)但是现在当我 pip 安装此包并导入已安装的 MyPackage 时(目前正在测试通过pip
从 GitHub 存储库安装)我在要使用 MyPackage 的脚本中收到 FileNotFound
异常(data.json)。但是,我看到data.json
文件确实安装在Lib/site-packages/MyPackage
中。
我在这里尝试读取包中的 json
文件是不是做错了什么?
请注意,在script.py
中,我试图将data.json
读取为open('data.json', 'r')
我是不是搞砸了有关数据文件路径的问题?
【问题讨论】:
欢迎来到 Stack Overflow。你能分享你的代码吗?如果你愿意,帮助你会更容易。 请提供完整的错误信息以及minimal reproducible example。 如果答案解决了您的问题,您应该在答案左侧accept it by clicking the green check mark。完整的解释见this meta thread。 【参考方案1】:您并没有搞砸什么,访问包资源只是有点棘手 - 主要是因为它们可以打包成您的 .json 可能严格来说不作为安装包的系统上的实际文件存在的格式(例如zip-app)。访问数据文件的正确方法不是通过指定路径(如"MyPackage/data.json"
),而是通过将其作为已安装包的资源进行访问(如"MyPackage.data.json"
)。这种区别可能看起来很迂腐,但它可能很重要。
无论如何,访问应该使用内置的importlib.resources
模块:
import importlib.resources
import json
with importlib.resources.open_text("MyPackage", "data.json") as file:
data = json.load(file)
# you should be able to access 'data' like a dictionary here
如果您碰巧使用低于 3.7 的 python 版本,则必须从 pyPI 将其安装为 importlib_resources
。
【讨论】:
啊太棒了!我发布答案后才看到这个。我会试试这个,谢谢!有趣的是,我认为离散化现有脚本的一部分相对容易,但我在将近 2 小时后...哈 是的,打包代码很快就会变成一团糟=) 我想知道 Python 3.9 中是否发生了一些变化?AttributeError: 'WindowsPath' object has no attribute 'read'
对我而言,您的示例代码的精确副本崩溃了文档建议“上下文管理器提供了一个 pathlib.Path 对象”,因此我假设它按预期工作,但这会使您的示例无效。我错过了什么吗?
@MantasKandratavicius 嗯.. 不,你是对的。看来我上传了错误的代码,但仍然设法获得了一堆赞成票。 json.load
需要一个文件句柄,而不是路径对象,所以你需要先在那里调用open()
。现在已经修复了,谢谢指出。
您也可以使用importlib.resources.open_text
,如with importlib.resources.open_text("MyPackage", "data.json") as data_file: data = json.load(data_file)
,而不是使用double with's【参考方案2】:
我通过获取包所在位置的“相对路径”解决了这个问题。
self.data = self.load_data(path=os.path.join(
os.path.dirname(os.path.abspath(__file__)),
'data.json'))
load_data
只是读取数据文件
仍然非常欢迎任何建设性的批评。如果我帮不上忙,就不要尝试编写愚蠢的代码:)
【讨论】:
如果这是一个您可以完全控制的简单包,那么这样做可能就足够了。一种可能失败的情况是,如果您将软件包安装为压缩存档。以上是关于尝试在 Python 包中读取 JSON 文件的主要内容,如果未能解决你的问题,请参考以下文章