为什么这样不会运行陷入死循环呢?

Why does this not run into an infinite loop?

此代码摘自此线程中的答案 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")

我认为代码执行如下(作为main执行时python3foo3.py):
1. 打印 t1
2. 打印 m1
3. 输入函数A并打印a1
4. 从 foo3 导入 functionB,因此再次 运行 foo3。返回步骤 1
你能帮我纠正一下我的分析吗?

它不是 "run foo3 again",它 运行 又是 foo3.py 脚本。第一次foo3.py是运行ning是生产模块__main__,第二次是生产模块foo3.py.

行为实际上(几乎)就好像 你有一个名为 __main__.py 的文件和另一个名为 foo3.py 的文件 =65=] 与这些完全相同的内容然后你 运行 python __main__.py。这就是正在发生的事情。

只是,Python 伪造了它,这样 它看起来好像程序是从名为 __main__.py 的脚本启动的,无论实际 Python 文件是。唯一相反的标志是 __file__ 会告诉实际脚本的文件名,即 /spam/ham/eggs/foo3.py.


它不会进入无限循环的原因是 importsys.modules 中寻找具有给定名称的模块 - 如果它已经存在,它不会执行任何新的文件。启动时Python会在sys.modules中为__main__创建一个入口,启动脚本(foo3.py)的代码在该模块范围内执行。

然后当它执行语句 import foo3 时,它将检查 foo3 是否在 sys.modules 中有一个条目。由于它不存在,因此创建了一个名为 foo3new 空模块,并将其放入 sys.modules 中,并在其中执行 foo3.py 的代码此新空模块的范围

最终执行了import第2次。这次 foo3sys.modules 中,所以导入不会创建或加载任何更多脚本,只是 returns 已经加载的模块。

要获得 "infinite" 循环,您可以在再次导入 foo3 之前从 sys.module 删除 已经导入的模块引用:

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