Python3导入异常

Python 3 import anomaly

考虑以下目录结构,

parent
├── __init__.py
├── mod1.py
├── mod2.py
└── mod3.py

文件内容和python版本是,

$ cat __init__.py 
from . import mod1
hello = "parent Hello"

$ cat mod1.py
from . import mod2
hello = "parent.mod1 Hello"

$ cat mod2.py
hello = "parent.mod2 hello"

$ cat mod3.py
hello = "parent.mod3 Hello"

$ python3 -V
Python 3.5.2

现在在交互式会话中我得到以下行为,

>>> import parent
>>> parent.mod1
<module 'parent.mod1' from '/home/codeman/mydata/local/tmp/parent/mod1.py'>
>>> parent.mod2
<module 'parent.mod2' from '/home/codeman/mydata/local/tmp/parent/mod2.py'>
>>> parent.mod3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'parent' has no attribute 'mod3'

当我只在 parent/__int__.py 文件中导入 mod1 时,为什么 parent.mod2 可以访问? (这是一个错误吗?)

我理解 parent.mod3 的 AttributeError 发生是因为当使用 import parent 语法简单地导入父级时,只有 __init__.py 文件中导入的模块是可访问的。

Whenever you import a module, Python creates a module object and stores it in the sys.modules dictionary. Subsequent imports of that same module will reuse the module object from sys.modules. Additionally, each time you import a submodule, the attribute is added to the parent module object.

There's one instance of sys.modules for a given Python process, and therefore in general there's only one instance of every module per Python 过程。 It means that if you have access to a module object, you also have access to its submodules that have been imported anywhere within the current process.

In this particular case, import package runs package/__init__.py, which imports package.mod1, which imports package.mod2. As a result, mod1 and mod2 are added to the "shared" parent module object, and you can access them.