考虑以下目录结构
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.mod2
文件中导入mod1
时,为什么parent/__int__.py
可以访问? (这是一个错误吗?)
我理解带有parent.mod3
的AttributeError是因为只有在使用__init__.py
语法明确导入父文件时才能访问import parent
文件中导入的模块。
答案 0 :(得分:1)
每当导入模块时,Python都会创建一个模块对象并将其存储在sys.modules
字典中。后续导入同一模块将重用sys.modules
中的模块对象。此外,每次导入 sub 模块时,该属性都会添加到父模块对象中。
对于给定的Python进程,有一个sys.modules
实例,因此通常每个Python进程只有一个模块的实例。这意味着如果您有权访问模块对象,您还可以访问已在当前进程中的任何位置导入的子模块。
在这种特殊情况下,import package
运行 package / __ init __。py ,导入package.mod1
,导入package.mod2
。因此,mod1
和mod2
会添加到“共享”parent
模块对象中,您可以访问它们。