此代码是从该线程What does if __name__ == "__main__": do?的答案中提取的
# Suppose this is foo3.py.
def functionA():
print("a1")
from foo3 import functionB
print("a2")
functionB()
print("a3")
def functionB():
print("b")
print("t1")
print("m1")
functionA()
print("m2")
print("t2")
我认为代码执行如下(当作为主要python3 foo3.py执行时):
1.打印t1
2.打印m1
3.输入functionA并打印a1
4.从foo3导入functionB,从而再次运行foo3。返回步骤1
你能帮我纠正我的分析吗?
答案 0 :(得分:1)
它不会“再次运行foo3
”,它会再次运行 foo3.py
脚本。 foo3.py
第一次运行是为了生产模块__main__
,第二次是生产模块foo3.py
。
该行为实际上(几乎)是 ,就像您有一个名为__main__.py
的文件和另一个名为foo3.py
的文件两者一样,它们完全相同内容,然后运行python __main__.py
。这就是正在发生的事情。
只有Python伪造它,以便无论实际的Python文件是什么,它看起来都好像程序是从名为 __main__.py
的脚本启动的。唯一相反的迹象是__file__
会告诉实际脚本的文件名,即/spam/ham/eggs/foo3.py
。
之所以不会进入无限循环,是因为import
在sys.modules
中查找具有给定名称的模块-如果该模块已经存在,它将不执行任何新文件。启动后,Python将在__main__
中为sys.modules
创建一个条目,并且启动脚本(foo3.py
)的代码在此模块的范围内执行。
然后,在执行语句import foo3
时,它将检查foo3
在sys.modules
中是否有条目。由于不存在,因此创建了名为foo3
的 new 空模块,并将其放入sys.modules
中,并且在此范围内执行foo3.py
的代码新的空模块。
它最终执行import
第二次时间。这次foo3
中有 sys.modules
,因此导入不会创建或加载任何脚本,只会返回已加载的模块。
要获取“无限”循环,可以在再次导入sys.module
之前,从foo3
中删除已导入的模块引用:
import sys
def functionA():
print("a1")
if 'foo3' in sys.modules:
del sys.modules['foo3']
from foo3 import functionB
print("a2")
functionB()
print("a3")
def functionB():
print("b")
print("t1")
print("m1")
functionA()
print("m2")
print("t2")
运行时您会得到
[....]
File ".../foo3.py", line 7, in functionA
from foo3 import functionB
File ".../foo3.py", line 17, in <module>
functionA()
File ".../foo3.py", line 7, in functionA
from foo3 import functionB
RuntimeError: maximum recursion depth exceeded while calling a Python object
答案 1 :(得分:-2)
如果仅从函数中导入函数,为什么要运行foo3?