为什么__all__只包含字符串对象?

Nir*_*Izr 1 python pylint

今天我遇到了以下的pylint错误:

invalid-all-object(E0604):

__all__中的无效对象%r必须仅包含在__all__中出现无效(非字符串)对象时使用的字符串.

而且我很好奇为什么直接暴露对象被认为是错误的?

Die*_*Epp 6

如果暴露字符串以外的其他内容,Python 将抛出异常。这就是 pylint 给出该错误的原因,因为代码不正确。

文件 mymodule.py:

def func():
    pass
__all__ = [func]
Run Code Online (Sandbox Code Playgroud)

现在运行:

from mymodule import *
Run Code Online (Sandbox Code Playgroud)

您将得到一个TypeError.

回溯(最近一次调用最后一次):
  文件“<stdin>”,第 1 行,位于 <module> 中
类型错误:属性名称必须是字符串,而不是“函数”

原因是它__all__用于命名模块对象上的属性。这就是该机制的工作原理。如果你想修改Python的导入机制,以便你可以将对象放在那里,我想你可以,但它只适用于某些类型的对象(函数和类可以工作,但常量不起作用,你也不会能够重命名函数和类)。


jwo*_*der 6

因为它应该是列表的名称,并不值:

如果标识符列表被star('*')替换,则模块中定义的所有公共名称都绑定在import语句发生范围的本地名称空间中.

模块定义的公共名称是通过检查模块命名空间的命名空间来确定的__all__; 如果已定义,则它必须是一个字符串序列,这些字符串是由该模块定义或导入的名称.给出的名称__all__都被认为是公开的,并且必须存在.如果__all__未定义,则公共名称集包括在模块命名空间中找到的所有名称,这些名称不以下划线字符('_')开头.__all__应该包含整个公共API.它旨在避免意外导出不属于API的项目(例如在模块中导入和使用的库模块).[ 语言参考 ]