Python包是否应该避免自身名称出现在自身命名空间中?
问题解答
1. 命名空间设计规范相关
目前Python官方PEP规范没有强制要求包是否需要将自身名称纳入自身命名空间,但行业公认的最佳实践是不要做这种冗余设计,对应的逻辑如下:
- Python包的命名空间设计核心是暴露对外提供的能力,包括子模块、函数、类、常量等,自身名称属于完全冗余的信息,不存在任何合理的使用场景
- 如你测试所见,numpy、scipy等绝大多数主流包都遵循该实践,少数存在该现象的包(如tqdm、旧版本setuptools)均为历史导入逻辑的副作用,而非刻意设计的功能
- 该冗余配置除了你提到的递归遍历
dir()触发死循环的问题外,还会误导用户误以为存在同名子模块,增加API的理解成本
2. 避免自身名称出现在命名空间的实现方法
该现象和打包分发配置(pyproject.toml、setup.cfg、setup.py)没有关联,几乎都是包根目录的__init__.py导入逻辑不规范导致的,按以下步骤排查即可解决:
- 首先检查
__init__.py中是否存在直接导入自身包的代码,比如import 你的包名、from . import 你的包名这类语句,直接删除即可 - 排查相对导入逻辑是否有误:如果你的子模块中使用了
from 你的包名 import xxx这类绝对导入语句,同时__init__.py中又将子模块的内容全量导入(如from .core import *),就可能将自身包的引用带入命名空间,将子模块的导入改为更安全的相对导入即可解决 - 检查
__init__.py中定义的__all__变量,是否误将自身包名写入了该列表,__all__会直接控制dir()返回的公开内容,删除对应的自身包名字段即可
验证修改是否生效的方法非常简单:修改完成后在项目根目录启动Python解释器,导入你的包后执行"你的包名" in dir(你的包名),返回False即符合要求。
内容的提问来源于stack exchange,提问作者DoodleVib
相关产品推荐
相关产品推荐

