setuptools的find_packages是否仍要求包包含__init__.py文件?
关于setuptools
find_packages与__init__.py的识别规则 这个问题戳中了Python包管理从传统到现代过渡的一个关键细节,我来给你拆解清楚:
传统行为:必须有__init__.py
在Python 3.2及更早的版本中,一个目录必须包含__init__.py文件才能被识别为Python包,setuptools的find_packages()函数完全遵循这个规则——官方文档早期提到的“只有包含__init__.py文件的包才会被识别”,就是对应这个阶段的行为。当时没有__init__.py的目录只会被当作普通文件夹,不会被当作包处理。
现代变化:Python支持无__init__.py,但find_packages()默认仍需它
Python 3.3引入了隐式命名空间包(Implicit Namespace Packages),允许没有__init__.py的目录作为包的一部分,这让跨项目的命名空间共享变得更方便。但注意:
- setuptools的
find_packages()函数默认行为没有改变,它依然只会扫描包含__init__.py的目录,将其识别为可安装的包; - 如果你想让setuptools识别没有
__init__.py的命名空间包,需要使用专门的find_namespace_packages()函数(从setuptools 40.0.0版本开始提供),这个函数会兼容隐式命名空间包的规则,无需__init__.py就能识别包目录。
总结
- 使用
find_packages():默认要求目录下存在__init__.py才能被识别为包; - 使用
find_namespace_packages():支持无__init__.py的现代包结构,符合Python 3.3+的特性; - Python本身已经不再强制要求
__init__.py标记包,但setuptools的传统find_packages()保留了旧有规则,需要用新函数适配现代场景。
内容的提问来源于stack exchange,提问作者Michele Piccolini
相关产品推荐
相关产品推荐

