
本文详解在发布 PyPI 包时,如何确保内置 JSON 数据文件被正确包含并安全读取,避免 FileNotFoundError,涵盖 MANIFEST.in 配置、setup.py 设置及推荐的现代资源加载方式。
本文详解在发布 pypi 包时,如何确保内置 json 数据文件被正确包含并安全读取,避免 `filenotfounderror`,涵盖 `manifest.in` 配置、`setup.py` 设置及推荐的现代资源加载方式。
在将 Python 包(如用于查询印度机构缩写映射的 Abbre)发布至 PyPI 时,一个常见却易被忽视的问题是:包内附带的数据文件(如 output_2.json)未随代码一同安装,导致运行时报 FileNotFoundError。错误日志明确指出:No such file or directory: 'Abbre\output_2.json'——这说明 Python 在安装后的 site-packages 目录中未能找到该文件,根本原因在于数据文件未被 setuptools 正确声明为“包数据”。
✅ 正确打包数据文件的两种方式(任选其一)
方式一:使用 MANIFEST.in(适用于源码分发)
在项目根目录(与 setup.py 同级)创建 MANIFEST.in 文件,内容如下:
include Abbre/output_2.json
⚠️ 注意路径分隔符使用正斜杠 /(跨平台兼容),且路径需相对于项目根目录。若 JSON 文件位于子目录(如 my_data/output_2.json),则应写为 include Abbre/my_data/output_2.json。
方式二:在 setup.py 中显式声明(推荐)
更新 setup.py 的 setup() 函数参数,添加 package_data 和 include_package_data=True:
from setuptools import setup, find_packages
setup(
name="Abbre",
version="0.1.2",
packages=find_packages(),
package_data={
"Abbre": ["output_2.json", "my_data/output_2.json"], # 列出所有需打包的非 Python 文件
},
include_package_data=True,
# 其他参数...
)
✅ package_data 是最直接、可维护性高的方案,尤其适合结构清晰的包。
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
? 错误写法警示:绝对/相对路径硬编码
原始代码中 open('Abbreoutput_2.json', 'r') 是典型反模式:
- 使用硬编码相对路径,依赖当前工作目录(CWD),而非包安装位置;
- Windows 下反斜杠 可能引发转义问题(应使用原始字符串 r"Abbreoutput_2.json" 或正斜杠);
- 最关键的是:此路径不指向已安装包内的实际文件位置。
✅ 推荐读取方式:使用 importlib.resources(Python 3.7+,现代标准)
替代已弃用的 pkg_resources,更简洁、安全、无额外依赖:
import json
from importlib import resources
def Abbreviation(arr):
# Python 3.9+
with resources.files("Abbre").joinpath("my_data/output_2.json").open("r") as f:
loaded_dict = json.load(f)
# Python 3.7–3.8 兼容写法
# with resources.open_text("Abbre", "my_data/output_2.json") as f:
# loaded_dict = json.load(f)
arr1 = arr.lower().strip()
result = loaded_dict.get(arr1)
if result is not None:
return [result] # 返回列表,避免重复 print
else:
print("The data is not available")
return []
? 验证是否打包成功
发布前,本地构建并检查生成的源码包(.tar.gz)或轮子(.whl):
python -m build tar -tzf dist/Abbre-0.1.2.tar.gz | grep output_2.json # 应有输出
安装后也可在 Python 中验证:
import Abbre print(Abbre.__file__) # 查看安装路径 # 然后手动检查该目录下是否存在 my_data/output_2.json
? 总结关键点
- 数据文件必须通过 package_data 或 MANIFEST.in 显式声明,否则不会进入分发包;
- 运行时务必使用资源定位 API(importlib.resources)读取,而非硬编码路径;
- 避免 pkg_resources(已标记为 legacy),优先采用标准库方案;
- 测试环节需在全新虚拟环境中 pip install . 后验证功能,确保端到端可用。
遵循以上步骤,你的 Abbre 包即可稳定读取内置 JSON 数据,顺利通过 PyPI 审核并被用户可靠使用。










