使用distutils setup()构建Python3包的最小数据包含方法及数据缺失排查
问题1:使用distutils的setup()构建Python 3包时,包含数据的最简用法
在distutils里,包含包内数据文件最直接简单的方式是通过package_data参数指定,给你举个实际场景的例子:
假设你的包目录结构是这样的:
mypkg/ __init__.py # 必须有这个文件,让Python识别为合法包 config.ini # 要包含的单个数据文件 data/ logo.png # 子目录里的数据文件
对应的setup.py最简写法如下:
from distutils.core import setup setup( name="mypkg", version="1.0.0", packages=["mypkg"], # 指定要打包的目标包 package_data={ # 键是包名,值是相对于包目录的文件路径列表 "mypkg": ["config.ini", "data/*"] } )
执行python setup.py build后,config.ini和data目录下的所有文件都会被自动复制到build/lib/mypkg对应的位置中。
如果你的数据都是包内的非代码文件,也可以用include_package_data=True简化配置,但前提是要额外写一个MANIFEST.in文件声明要包含的文件,相对来说package_data的写法更直接,不需要额外配置文件,是真正的“最简”用法。
问题2:执行build后数据未出现在build/lib/mypkg的排查与解决
根据你描述的情况,大概率是以下几个常见问题之一,你可以逐一排查:
- 包目录缺少
__init__.py:distutils只会把包含__init__.py的目录识别为Python包,如果你的mypkg目录下没有这个文件,setup脚本不会把它当作包处理,自然不会复制里面的数据文件,赶紧补上这个空文件试试。 package_data的路径配置错误:要注意package_data的键必须是你的包名(比如"mypkg"),而值是相对于包目录的路径。比如数据文件在mypkg/data/下,你得写"data/*"而不是"mypkg/data/*"或者其他错误路径。- 没指定
packages参数:如果setup里没写packages=["mypkg"],distutils不知道要打包哪个包,也就不会处理包内的package_data配置,一定要明确指定要打包的包名。 - 数据文件不在包目录内:如果你的数据文件是和setup.py同级的(比如根目录下的data文件夹),那
package_data是不起作用的。如果想让数据跟着包走,最好把数据移到mypkg目录下;如果必须放在外部,可以用data_files参数,但这个参数是把文件安装到系统固定路径,而非包目录里。 - 使用
include_package_data=True但没配置MANIFEST.in:如果你用了这个参数,必须在MANIFEST.in里写清楚要包含的文件,比如include mypkg/data/*,否则distutils不知道要包含哪些文件。
你可以对照自己的目录结构和setup脚本,检查以上几点,应该就能找到问题所在啦。
内容的提问来源于stack exchange,提问作者Cole Robertson




