让我们在Python3包中使用__init__.py
:
from .mod1 import *
from .mod2 import *
from .mod3 import *
__all__ = mod1.__all__ + mod2.__all__ + mod3.__all__
代码看起来非常简单并且做了预期的事情:它从模块mod1,mod2和mod3导入这些模块放入__all__
列表的所有符号,然后是所有三个__all__
的摘要列表已创建。
我试图在模块中运行相同的代码,即不在__init__.py
中。它导入了三个模块,但mod1
,mod2
和mod3
是未定义的变量。
(顺便说一句,如果您在原始__init__.py
上运行pylint,您也会收到此错误。)
同一语句from .mod1 import *
在mod1
中执行时会创建一个__init__.py
对象,但不会在其他位置创建它。为什么呢?
__init__.py
是一个特殊文件,但直到现在,我还以为它的名字很特别。
答案 0 :(得分:1)
根据documentation,这是预期的行为:
当使用任何机制(例如
importlib
API,import
或import-from
语句或内置__import__()
)加载子模块时,会在父模块的子模块对象的命名空间。例如,如果包spam
具有子模块foo
,则在导入spam.foo
后,spam
将具有绑定到子模块的属性foo
。
换句话说,当你在模块中执行from .whatever import something
时,你会神奇地获得一个whatever
属性绑定到模块。当然,您可以在__init__.py
中访问模块自己的属性,就好像它们被定义为变量一样。当你在另一个模块中时,你无法做到。在这个意义上,__init__.py
确实很特别。