简短回答
那么在__init__.py
中,from packages import *
实际上意味着什么?
__init__.py
导入了它本身。
解释
你只能导入模块,而不能导入包。包只是模块或子包的容器。当你“导入”一个包时,实际上导入的是模块__init__.py
。
这是__init__.py
的内容:
from packages import mod
将模块
mod
导入到
__init__.py
中。因此,通过
packages.mod
在
main.py
中可以使用它(请记住
packages
由
__init__.py
表示)。
当您更改
__init__.py
的内容时:
from packages import *
你正在导入模块
__init__.py
,这个文件和你当前所在的文件是完全相同的。这样做可以工作(第二次导入只会触发在
sys.modules
中查找),但不会给你
mod
的内容。
这意味着你可以使用:
from module import *
但是如果一个__init__.py
文件为空,你就不能明智地使用它:
from package import *
由于
package
实际上是由
__init__.py
表示的,而且里面还没有任何内容。您可以检查这一点(交互式或在文件中):
>>> import packages
>>> print(packages)
<module 'packages' from '/.../packages/__init__.py'>
在
__init__.py
中,您可以编写:
from packages.mod import *
然后在
main.py
中:
print packages.hello()
工作原理。因为函数hello()
现在位于文件__init__.py
的全局命名空间中。
正如mozman的回答中所提到的,您可以在__init__.py
中使用__all__
列出模块,如果使用from packages import *
,则应该被导入。这是为这种情况而设计的。
__init__.py
仅包含此内容:
__all__ = ['mod']
现在你可以在
main.py
中这样做:
from packages import *
print mod.hello()
如果您扩展您的
__init__.py
:
__all__ = ['mod']
from packages import *
你可以在
main.py
中完成这个操作:
import packages
print packages.mod.hello()
但是如果你从__init__.py
中删除from packages import *
:
__all__ = ['mod']
你会收到一个错误:
AttributeError: 'module' object has no attribute 'mod'
因为
__all__
仅用于
from packages import *
的情况。
现在我们回到
__init__.py
导入自身。
from package import *
这个命令,因为编译时不会出现错误,只有在打印时才会显示“没有模块'mod'”。所以这个命令是有效的,只是我对代码的作用感到困惑。 - andio__init__.py
文件会被隐式地执行,并且它定义的对象会绑定到包命名空间中的名称上。” - Jim Ratliff__init__.py
。这本质上就是你所说的,不是吗? - Mike Müller