Python中__all__能否为对象列表而非字符串?合规性问询
关于__all__的规范要求与对象列表的“意外可行”问题
首先得明确:Python官方规范里,__all__必须是字符串序列。翻Python模块文档就能看到,它的核心作用是明确列出模块对外暴露的公共API,每个元素都对应着导出名称的字符串。
那为什么你用对象列表能跑起来?这其实是CPython解释器的一个未被文档化的“隐藏兼容逻辑”——当它处理__all__时,如果遇到非字符串元素,会尝试读取该对象的__name__属性来当作要导出的名称(比如函数、类、模块这类自带__name__的对象就刚好能凑效)。但这绝对不是标准行为,换个Python实现(比如PyPy)说不定就跑不起来,而且未来CPython版本也完全可能砍掉这个兼容逻辑。
至于官方为什么要求必须用字符串列表,主要有这几个原因:
- 清晰直观:字符串直接对应名称,其他开发者一眼就能看懂哪些是模块的公共API,不用去猜对象的
__name__是什么。 - 工具友好:像mypy这类静态检查器、Sphinx这类文档生成工具,都是严格遵循官方规范的。它们会默认
__all__是字符串序列,用对象列表自然会触发类型错误,甚至导致工具无法正常工作。 - 避免意外:如果你的
__all__里放了没有__name__的对象(比如普通实例),或者对象的__name__和实际导出的名称不匹配,那from ... import *就会直接报错,或者导入完全不符合预期的内容。
所以结论是:虽然你现在用对象列表能跑,但这只是个偶然的“幸运”情况,完全不应该依赖。严格按照规范用字符串列表,才能保证你的代码在不同环境下都能正常工作,也能让其他工具和开发者更好地理解你的代码。
内容的提问来源于stack exchange,提问作者psarka
相关产品推荐
相关产品推荐

