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

时间:2017-01-25 19:33:12

标签: python pylint

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

  

invalid-all-object(E0604):

     

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

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

2 个答案:

答案 0 :(得分:6)

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

  

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

     

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

答案 1 :(得分:3)

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

文件mymodule.py:

def func():
    pass
__all__ = [func]

现在运行:

from mymodule import *

您将获得TypeError

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: attribute name must be string, not 'function'

原因是__all__用于命名模块对象的属性。这就是机制的运作方式。如果你想修改Python的导入机制,以便你可以把对象放在那里,我想你可以,但它只适用于某些类型的对象(函数和类可以工作,但常量不起作用,并且你将无法重命名函数和类。)