如何将非Python编写的额外文件包含到Python软件包中
配置不生效的核心原因
package_data 配置的键必须是Python包名,而非目录名。你配置中写的templates不是独立Python包(目录下没有__init__.py),它只是projectname包下的子目录,所以匹配规则无法生效。
正确配置方法
方法1:仅修改setup.py(推荐,配置更集中)
首先将导入的distutils.core替换为setuptools(distutils已停止维护,setuptools是目前官方推荐的打包工具),再修改package_data配置即可,完整示例如下:
from setuptools import setup setup( name = 'projectname', packages = ['projectname'], version = '0.1', license='MIT', description = 'my description', author = 'FULL NAME', author_email = 'example@gmail.com', url = 'https://github.com/repo', download_url = 'https://github.com/repo/.../v_01.tar.gz', keywords = ['keywords'], install_requires=[ 'opencv-python', 'numpy' ], classifiers=[ 'Development Status :: 3 - Alpha', 'Intended Audience :: Developers', 'Topic :: Software Development :: Build Tools', 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 3', ], # 正确的非代码文件包含配置 package_data = { # 键为对应的Python包名,值为相对于包根目录的文件匹配规则 'projectname': ['templates/*'], } )
方法2:通过MANIFEST.in配置(适合复杂多目录非代码文件场景)
如果项目需要包含大量规则复杂的非代码文件,可以用MANIFEST.in统一管理:
- 在setup.py同级的项目根目录下新建名为
MANIFEST.in的文件,写入以下内容:
recursive-include projectname/templates *
- 在setup.py的
setup()参数中添加include_package_data=True即可,不需要额外配置package_data。
验证和使用注意事项
- 打包完成后可以执行
tar -tf 生成的tar.gz包路径,检查文件列表中是否包含projectname/templates下的目标文件。 - 代码中读取这些非Python文件时,不要使用相对路径直接读取,建议用Python标准库
importlib.resources(Python3.7+内置)按包路径读取,避免不同安装方式下路径匹配失败,示例如下:
from importlib import resources import projectname # 读取templates下的file1.prototxt文件 with resources.as_file(resources.files(projectname).joinpath("templates/file1.prototxt")) as f_path: # f_path就是文件的实际绝对路径,可直接传入读取逻辑 with open(f_path, 'r', encoding='utf-8') as f: content = f.read()
内容的提问来源于stack exchange,提问作者questioning
相关产品推荐
相关产品推荐

