Python中的__all__模块级变量是用来做什么的?

28
我在Python/Lib源代码中经常看到它,但不知道它的作用。 我认为它用于限制模块中可访问的成员。 因此,只有__all__中的元素会显示在dir(module)中。
我做了一个小例子,发现它并没有按照我的预期工作。
那么,Python中的__all__模块级变量是用来干什么的?

4
类似问题在这里:https://dev59.com/mnVD5IYBdhLWcg3wO5AD - viam0Zah
3个回答

52

它有两个作用:

  1. 阅读源代码的任何人都会知道其公开的API是什么。这并不能防止他们查看私有声明,但提供了一个很好的警告不要这样做。

  2. 当使用from mod import *时,只导入__all__中列出的名称。在我看来,这并不是很重要,因为导入所有东西是一个非常糟糕的想法。


8
不只是任何人,还包括任何东西。一些API文档工具会考虑__all__属性。例如pydoc就会,而我相信epydoc和类似的工具也会这样做。 - mzz
当我们使用'import *'时,'.py'文件中的公共变量在另一个文件中是可用的,即使它们没有包含在__all__中。请问有人可以澄清一下这个问题吗? - Alchemist777
Sphinx 也尊重 __all__ - Rafe

8

http://docs.python.org/tutorial/modules.html#importing-from-a-package

当用户输入 from sound.effects import *时会发生什么呢?理想情况下,我们希望文件系统会查找包中存在哪些子模块并将它们全部导入。但这可能需要很长时间,并且导入子模块可能会产生不必要的副作用,这些副作用应该仅在显式导入子模块时发生。

唯一的解决方案是由包的作者提供一个明确的索引。import 语句使用以下惯例:如果一个包的__init__.py代码定义了一个名为__all__的列表,那么它被认为是在遇到from package import *语句时应该导入的模块名称列表。当发布包的新版本时,包作者需要更新这个列表。如果他们认为从他们的包中导入*没有任何用处,他们也可以选择不支持它。


4

它控制着当您进行名称空间时所拉入的内容。

from blah import *

请查看从包中导入*

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接