为什么这不会陷入无限循环?

时间:2019-08-17 06:32:12

标签: python namespaces main python-module

此代码是从该线程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
你能帮我纠正我的分析吗?

2 个答案:

答案 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


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

然后,在执行语句import foo3时,它将检查foo3sys.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?