我为什么要在__init__的python包中使用__all__?

Zac*_*Zac 3 python package

我已经阅读过有人可以在Python中解释__all__吗?我明白它只影响from ... import *陈述,但我无法弄清楚一个真实的用例.__all__当我可以简单地避免在__init__命名空间中导入这些名称时,为什么要在(DRY!)中重复导出的名称?

例:

mypackage/__init__.py

from a import A
Run Code Online (Sandbox Code Playgroud)

mypackage/a.py

A = "A"
A1 = "A1"
Run Code Online (Sandbox Code Playgroud)

mypackage/b.py

B = "B"    
Run Code Online (Sandbox Code Playgroud)

然后在python中:

>>> from mypackage import *
>>> A
'A'
>>> 
>>> A1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'A1' is not defined
>>> b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
Run Code Online (Sandbox Code Playgroud)

正如你所看到的A是在命名空间,但A1b没有.我为什么要定义__all__ = ["A"]

Jam*_*lls 6

您要在程序包中定义的唯一时间是列出用户执行时要导出的"导出"成员的名称:__all____init__.py

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

这在6.4.1中有记录.从包中导入*

注意:如果__all__在包中定义,则默认行为如下(来自文档):

如果__all__未定义,则sound.effects import*中的语句不会将包sound.effects中的所有子模块导入当前名称空间; 它只确保已导入包sound.effects(可能运行任何初始化代码 __init__.py),然后导入包中定义的任何名称.这包括定义的任何名称(以及显式加载的子模块)__init__.py.它还包括由以前的import语句显式加载的包的任何子模块.考虑以下代码:

对此的"天真"解释可以是:

如果你没有定义__all__; a from package import *将带来包装中的所有东西以及在 pacakge中进口的任何东西__init__.py.

  • @Zac您可能想要初始化包并需要导入标识符才能做到这一点。但是您可能不想将它们与您的包一起导出。所以你可以使用`__all__`来控制它。 (4认同)
  • @Zac你可以限制'*'附带的内容。在你的例子中它将带来一切。 (2认同)