Python跨依赖调用包内JSON文件报错:找不到指定文件或目录
问题解决:Python包内资源文件读取失败
问题背景
我有如下Python包结构:
MyPackage/ - assets/ - __init__.py - asset.py - vulnerability_template.json - warn.json - setup.py
已在setup.py中配置将JSON文件包含进包内,asset.py中的读取函数如下:
def get_json_asset(file_name: str) -> dict: try: with open(file_name) as f: return json.loads(f.read()) except Exception as e: raise e
当从依赖该包的其他项目中调用get_json_asset时,报错:No such file or directory: 'vulnerability_template.json'
问题原因
直接使用文件名调用open()时,Python会以当前运行代码的工作目录为基准查找文件,而非包内assets目录的路径,导致包安装后无法定位到内置的JSON文件。
解决方案
方案1:基于模块路径构建绝对路径(兼容所有Python版本)
修改asset.py代码,通过模块所在目录拼接文件绝对路径:
import json import os def get_json_asset(file_name: str) -> dict: # 获取当前模块所在的绝对目录 module_dir = os.path.dirname(os.path.abspath(__file__)) # 拼接目标JSON文件的绝对路径 file_path = os.path.join(module_dir, file_name) try: with open(file_path, 'r') as f: return json.load(f) except Exception as e: raise e
方案2:使用importlib.resources(Python 3.9+推荐)
利用Python标准库的importlib.resources管理包内资源,更符合现代包规范:
import json from importlib.resources import files def get_json_asset(file_name: str) -> dict: # 定位到MyPackage.assets包下的目标文件 file_path = files('MyPackage.assets').joinpath(file_name) try: with open(file_path, 'r') as f: return json.load(f) except Exception as e: raise e
确认setup.py配置
确保setup.py中正确声明了包数据,避免JSON文件被遗漏:
from setuptools import setup, find_packages setup( name='MyPackage', packages=find_packages(), package_data={ 'MyPackage.assets': ['*.json'], }, )
内容的提问来源于stack exchange,提问作者Oren Shamun
相关产品推荐
相关产品推荐

