如何从Python Wheel包读取JSON文件?本地正常打包后返回空字典
问题原因
本地运行时,脚本的工作目录是项目根目录,相对路径api/workflow/cfg能正确指向JSON文件所在位置;但打包安装后,包文件会被部署到Python的site-packages目录下,此时运行脚本的工作目录不一定是包的安装目录,直接使用相对路径会找不到目标文件,导致函数返回空字典。
解决步骤
1. 确保setup.py正确包含数据文件
在setup.py中配置package_data,确保JSON文件被打包进whl包。如果api/workflow/cfg目录下没有__init__.py,先创建一个空的__init__.py将其声明为Python包,然后修改setup.py:
from setuptools import setup, find_packages setup( name="MyPackage", version="0.1", packages=find_packages(), package_data={ "api.workflow.cfg": ["*.json"], }, include_package_data=True, )
2. 修改文件读取逻辑
放弃相对路径,通过Python的包资源定位API获取文件的绝对路径,推荐使用importlib.resources(Python 3.7+):
import json from pathlib import Path from typing import Dict import importlib.resources # 假设wd是你定义的数据类/类 def read_cfg() -> Dict[str, wd]: wf: Dict[str, wd] = {} # 获取包内cfg目录的绝对路径 with importlib.resources.path("api.workflow.cfg", "") as cfg_dir: for json_file in Path(cfg_dir).glob("*.json"): with open(json_file, encoding="utf-8") as f: definition = json.load(f) wf[definition["name"]] = wd(**definition) return wf
如果需要兼容Python 3.7以下版本,可以使用pkg_resources:
import json from pathlib import Path from typing import Dict import pkg_resources def read_cfg() -> Dict[str, wd]: wf: Dict[str, wd] = {} # 获取包内cfg目录的绝对路径 cfg_dir = pkg_resources.resource_filename("api.workflow", "cfg") for json_file in Path(cfg_dir).glob("*.json"): with open(json_file, encoding="utf-8") as f: definition = json.load(f) wf[definition["name"]] = wd(**definition) return wf
3. 重新打包并验证
执行python3.9 setup.py bdist_wheel重新生成whl包,安装后测试函数即可正常读取JSON文件。
内容的提问来源于stack exchange,提问作者Rakesh Shetty
相关产品推荐
相关产品推荐

