能否为setuptools的find_packages()指定多个源目录?
解决find_packages()识别多目录Python包的问题
我之前也遇到过类似的多源码目录打包问题,结合你的项目结构,给你几个可行的解决方案:
先搞清楚你之前尝试失败的原因
- 用
find_packages('proj/src1')时,工具只会递归搜索proj/src1目录下的包,自然找不到src2里的pkg3和根目录下的pkg4。 - 用
find_packages('proj')找不到包,大概率是你的setup.py放在了proj目录内部——这时候where='proj'会指向proj/proj(不存在的路径),当然搜不到东西。如果setup.py在proj外面,这个命令其实能搜到带src1.、src2.前缀的包,但这应该不是你想要的顶层包效果。
解决方案1:合并多个find_packages结果(自动发现,推荐)
如果不想手动列所有包,可以多次调用find_packages分别扫描不同源码目录,再合并结果,配合package_dir告诉setuptools每个包的位置:
from setuptools import setup, find_packages # 分别从不同目录查找包 pkg_from_src1 = find_packages(where="proj/src1") pkg_from_src2 = find_packages(where="proj/src2") pkg_from_root = find_packages(where="proj") # 找proj下的pkg4 # 合并所有包名 all_packages = pkg_from_src1 + pkg_from_src2 + pkg_from_root # 自动生成包路径映射 package_dir = {} # 映射src1下的包 for pkg in pkg_from_src1: package_dir[pkg] = f"proj/src1/{pkg}" # 映射src2下的包 for pkg in pkg_from_src2: package_dir[pkg] = f"proj/src2/{pkg}" # proj根目录下的pkg4不需要额外映射 setup( name="your-project-name", version="0.1.0", packages=all_packages, package_dir=package_dir, # 其他配置项... )
解决方案2:手动指定包路径(适合包数量少的场景)
如果你的包数量不多,直接在package_dir里逐个映射顶层包和对应路径更简单:
from setuptools import setup setup( name="your-project-name", version="0.1.0", package_dir={ "pkg1": "proj/src1/pkg1", "pkg2": "proj/src1/pkg2", "pkg3": "proj/src2/pkg3", "pkg4": "proj/pkg4" }, packages=["pkg1", "pkg2", "pkg3", "pkg4"], # 其他配置项... )
解决方案3:调整项目结构(长期最佳实践)
如果允许调整结构,推荐把所有源码包放到统一的src目录下——这是Python打包的标准做法,后续维护更省心:
proj +--src | +--pkg1 | | +-- (__init__.py and sources) | +--pkg2 | | +-- (__init__.py and sources) | +--pkg3 | | +-- (__init__.py and sources) | +--pkg4 | | +-- (__init__.py and sources) +--setup.py
这时setup.py只需要简单配置:
from setuptools import setup, find_packages setup( name="your-project-name", version="0.1.0", packages=find_packages(where="src"), package_dir={"": "src"}, # 告诉工具所有顶层包都在src目录下 # 其他配置项... )
内容的提问来源于stack exchange,提问作者betontalpfa
相关产品推荐
相关产品推荐

