如何将包含mp3音频文件的Python项目正确发布到PyPI?
解决方案
核心问题出在打包配置和资源路径读取方式两个环节,按下面步骤修改即可解决:
1. 先确认项目结构规范
如果你的xinqing.py是直接放在根目录的单文件,setuptools.find_packages是无法识别到的,这个方法只会识别带__init__.py的目录型包。如果是目录型包,结构应该是:
项目根目录 ├── setup.py ├── MANIFEST.in └── xinqing ├── __init__.py ├── xinqing.py ├── typing_long.mp3 └── 其他资源文件
如果是单文件结构,把setup.py里的packages参数替换为:
py_modules = ["xinqing"]
2. 修复资源打包配置
MANIFEST.in默认仅对源码包(sdist)生效,wheel包需要明确配置资源打包规则,两种方案二选一即可:
- 方案1:保留
include_package_data=True,同时在setup.py里新增package_data配置:
setuptools.setup( # 原有其他配置不变 package_data={ "xinqing": ["*.mp3", "*.wav"] }, )
- 方案2:删除
include_package_data=True,仅保留上面的package_data配置,也能正常打包资源。
3. 替换资源路径读取逻辑
不要手动拼接__file__路径,Python 3.4+ 官方提供了标准的包内资源读取工具importlib.resources,兼容性更强,不会出现路径找不到的问题:
# 导入官方资源处理库 from importlib import resources # 替换原来的路径拼接代码 # 注意这里第一个参数填你的包名,如果是单文件就填__name__,目录包填"xinqing" with resources.path("xinqing", "typing_long.mp3") as mp3_path: p = multiprocessing.Process(target=playsound, args=(str(mp3_path),)) # 原来的vlc播放代码也可以用这个mp3_path # sound = vlc.MediaPlayer(str(mp3_path))
如果需要兼容Python 3.8以下版本,可以安装importlib-resources回溯兼容包,然后把导入语句改为from importlib_resources import resources。
4. 验证后重新发布
- 本地执行
python setup.py bdist_wheel,找到生成的.whl文件,把后缀改为.zip解压,确认typing_long.mp3已经被打包到包目录下 - 本地执行
pip install dist/你生成的wheel包名.whl,测试运行没有问题后再用twine上传到PyPI
内容的提问来源于stack exchange,提问作者Yan Wen
相关产品推荐
相关产品推荐

