当shell import
模块一个时,我认为一个将导入两个并运行的代码两个所以它会自动导入三个。因此,模块的三个名称都将包含在dir()
中。
实际上,当我检查命名空间时,只有模块一个(见下文)。
如何在不包含模块两个和三个的命名空间的情况下打印'Hello'
?由于one.f1()
依赖于两个模块。
>>> ================================ RESTART ================================
>>> import one
in three
In two
in one
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'one']
>>> one.f1()
Hello
>>>
'one.py'
import two
print('in one')
def f1():
two.f2()
def f4():
print ('Hello')
'two.py'
import three
print ('In two')
def f2():
three.f3()
'three.py'
import one
print('in three')
def f3():
one.f4()
答案 0 :(得分:4)
每个模块都有自己的命名空间,包括主脚本。您只将模块one
导入主脚本命名空间。
其他模块分别导入模块one
和模块two
的命名空间。
实际上,仅导入才意味着您在当前命名空间中创建了对导入项(此处为模块对象)的引用。 Python将确保首先加载模块(当您看到正在执行的print()
语句时),然后实际导入(当前名称空间中名称的绑定)。
因此,声明import one
做了两件事:
one
,一次,如果尚未加载。这包括创建模块并在其中插入名称。one
绑定到模块。模块存储在sys.modules
;加载开始的那一刻它们就存储在那里。
在您的情况下,加载模块one
会触发另一个导入,因此Python会加载模块two
以满足该导入。这反过来会触发模块three
的导入。 three
导入one
,sys.modules
中已存在的模块。因此,名称one
不会出现问题,因为已经存在要绑定的模块。该模块仍然是空的(因为它仍处于加载过程中)。
完整的事件序列是:
import one
- > sys.modules
中没有这样的模块
sys.modules['one']
,加载代码并开始执行import two
- > sys.modules
sys.modules['two']
,加载代码并开始执行import three
- > sys.modules
中没有这样的模块
sys.modules['three']
,加载代码并开始执行import one
- >存在sys.modules['one']
,将one
绑定到sys.modules['one']
。print('in three')
f3
。three
three
绑定到sys.modules['three']
print ('In two')
f2
two
two
绑定到sys.modules['two']
print('in one')
f1
和f4
one
one.f1()
one.f1()
存在且已执行 - > two.f2()
two.f2()
存在且已执行 - > three.f3()
three.f3()
存在且已执行 - > one.f4()
one.f4()
存在并执行> print('Hello')
创建one.f4()
时,three.f3()
不存在尚的事实并不重要;只有在执行该函数时才会查找该名称。