如何从src子目录外添加package_data使其在安装时被正确部署?
解决方案
核心原理
你之前的方案失败本质都是路径匹配规则和wheel安装策略的问题:
include_package_data=True仅会将包目录内部的、被MANIFEST.in收录的文件作为包数据安装,根目录的template不属于任何包的内部路径,自然不会被安装- 直接写
package_data的路径默认是相对于包目录(你的场景下是src/deviceffs),不加回溯路径自然找不到根目录下的文件 data_files在wheel格式下默认安装路径是系统级共享目录,不是包目录,兼容性差不推荐使用
具体配置
不需要修改现有的pyproject.toml、setup.py,仅修改两个文件即可:
1. 修改MANIFEST.in
添加以下配置,确保根目录下的模板文件会被打进源码包:
include template/*.ini # 后续要加示例、文档等额外文件可以按相同规则扩展,比如 include examples/*、include docs/*.pdf
2. 修改setup.cfg
在原配置末尾新增options.package_data段落,用相对路径从包目录回溯到根目录匹配文件:
[options.package_data] deviceffs = # 相对于src/deviceffs目录向上回溯两层到项目根目录,匹配template下的所有ini文件 ../../template/*.ini
如果你希望安装后模板文件统一放在包内的template子目录下,可以将上述配置替换为:
[options.package_data] deviceffs = template/*.ini
同时在src/deviceffs下新建空的template目录,保留根目录的template文件即可,打包时会自动合并两个目录的内容。
代码中访问模板文件
你的Python版本是3.9,直接用标准库的importlib.resources读取即可,不需要硬编码路径:
from importlib.resources import files import deviceffs # 直接散在包根目录的读取方式 template_a_path = files(deviceffs) / "template_A.ini" # 如果是放在包内template子目录的读取方式 # template_a_path = files(deviceffs) / "template" / "template_A.ini" # 读取文件内容示例 with template_a_path.open("r", encoding="utf-8") as f: content = f.read()
验证方法
- 先删除旧的
dist、build、*.egg-info目录,避免缓存影响 - 执行
python -m build重新打包 - 解压生成的
.whl文件,检查deviceffs目录下是否存在对应的模板文件 - 安装完成后可执行以下代码确认文件路径:
import deviceffs from pathlib import Path print("包安装路径:", Path(deviceffs.__file__).parent)
到对应路径下即可找到安装的模板文件。
内容的提问来源于stack exchange,提问作者bicyclesonthemoon
相关产品推荐
相关产品推荐

