构建可发布至PyPI的pip包时,如何暴露子目录模块以供导入?
问题描述
我的项目结构如下:
repository/ |---- setup.py |---- package_name/ |---- __init__.py |---- module_a.py |---- subdir/ |---- __init__.py |---- module_b.py
通过pip install .安装包后,离开repository目录可以正常执行:
from package_name.module_a import ma
但执行以下代码时会报错ModuleNotFoundError: No module named 'package_name.subdir':
from package_name.subdir.module_b import mb
请问如何暴露子目录中的模块,使其能从包中被导入?我计划将该包上传至PyPI。
解决方案
要让子目录subdir被识别为包的一部分,只需在setup.py中正确配置包结构,以下是两种常用方法:
1. 自动发现所有子包(推荐)
修改setup.py,使用setuptools.find_packages()递归自动查找所有包含__init__.py的子目录作为包,无需手动维护包列表:
from setuptools import setup, find_packages setup( name="package_name", version="0.1.0", packages=find_packages(), # 自动识别主包和所有子包 # 补充其他必要配置:author、description、install_requires等 )
2. 手动指定包列表
如果需要精确控制暴露的包,可以手动列出主包和子包:
from setuptools import setup setup( name="package_name", version="0.1.0", packages=["package_name", "package_name.subdir"], # 明确列出主包和子包 # 补充其他必要配置 )
额外说明
- 确保子目录下的
__init__.py文件存在(你的项目已满足此要求),这是Python识别子目录为包的核心标志。 - 若想优化导入体验(比如允许
from package_name import mb),可在package_name/__init__.py中添加导入语句:
这属于可选操作,不影响子包本身的可导入性。from package_name.subdir.module_b import mb
内容的提问来源于stack exchange,提问作者Aditya Srivastava
相关产品推荐
相关产品推荐

