使用setuptools打包含数据文件的单模块本地包遇模块找不到问题
问题修复方案
一、核心问题诊断
- 包结构错误:
src目录下未创建与项目同名的子包,setuptools 默认会查找src下的子目录作为包,导致无法识别根目录下的__init__.py,安装后缺失主模块文件。 - 资源路径硬编码:
__init__.py中使用本地绝对路径读取数据文件,安装后该路径不存在,不符合包内资源读取规范。 - 无需命名空间包:这是单模块内部包,完全不需要设置命名空间。
二、分步修复
1. 调整项目目录结构
将src下的所有文件移到src/LUTs子目录中,让src作为包的根目录,实际包放在同名子文件夹内:
LUTs/ ├── pyproject.toml ├── MANIFEST.in ├── src/ │ └── LUTs/ │ ├── __init__.py │ ├── CountyFIPS.csv │ ├── SCCountyFIPS.pkl │ └── NationwideCountyFIPS.pkl
2. 修改pyproject.toml配置
更新package-data的目标包名,确保指向正确的子包:
[build-system] requires = ["setuptools", "setuptools-scm"] build-backend = "setuptools.build_meta" [project] name = "LUTs" description = "Lookup table utility; CRM tables, FIPS codes, etc." version = "0.9" dependencies = [ "bidict" ] [tool.setuptools] include-package-data = true [tool.setuptools.packages.find] where = ["src"] [tool.setuptools.package-data] LUTs = ["*.csv", "*.pkl"]
3. 修复__init__.py的资源读取逻辑
使用Python 3.9+推荐的importlib.resources读取包内资源,避免硬编码路径:
import pickle from bidict import bidict from importlib.resources import files, as_file # 读取南卡罗来纳州FIPS数据 with as_file(files("LUTs").joinpath("SCCountyFIPS.pkl")) as sc_path: with open(sc_path, mode='rb') as sc: sccounties = pickle.load(sc) # 读取全国FIPS数据 with as_file(files("LUTs").joinpath("NationwideCountyFIPS.pkl")) as us_path: with open(us_path, mode='rb') as us: uscounties = pickle.load(us) SC_COUNTIES = bidict(sccounties) US_FIPS = bidict(uscounties)
4. 更新MANIFEST.in(可选)
为兼容源码包(sdist)打包,更新路径指向子包:
include src/LUTs/*.pkl include src/LUTs/*.csv
三、重新打包安装
执行以下命令完成修复后的构建与安装:
# 清理旧构建文件 rm -rf build dist *.egg-info # 重新构建包 python -m build # 强制安装新包 pip install --force-reinstall dist/LUTs-0.9-py3-none-any.whl
验证:在Python环境中执行import LUTs,若能正常导入并访问LUTs.SC_COUNTIES、LUTs.US_FIPS,则说明修复成功。
内容的提问来源于stack exchange,提问作者Vijay Tripathi
相关产品推荐
相关产品推荐

