在这种情况下,python如何避免无限递归?

时间:2019-03-31 04:28:17

标签: python

我正在使用this question的公认答案,以更好地理解为什么在python中必须使用if __name__=='__main__'构造的原因。我从答案中了解到的是,如果foo.py是使用python foo.py从命令行运行的,则变量__name__的值是'__main__',因此, if __name__=='__main__'块被执行。另一方面,如果模块是使用import foo从另一个脚本导入的,则__name__的值是"foo"。因此,if块中的内容未执行。

然后,答案显示了一个使用foo2.pyfoo3.py的示例,并建议比较结果。 foo2的代码是:

# Suppose this is foo2.py.

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")

foo3的代码是:

# 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")

然后我分别使用python foo2.pypython foo3.py来运行。这些是我得到的结果:

(base) D:\TEMP\try>python foo2.py
t1
m1
a1
t1
m1
a1
a2
b
a3
m2
t2
a2
b
a3
m2
t2

我对第二个(foo3.py)感到困惑。 functionB导入后,我期待着

t1
m1
a1
t1
m1
a1
t1
m1
a1
... to infinity

因为将functionB嵌套在functionA中会导致无限递归。但是python“知道”某种方式可以避免这种情况...

这里的逻辑是什么?这怎么不会发生?

谢谢。

2 个答案:

答案 0 :(得分:4)

Python import语句很聪明,可以跟踪已导入的内容。

在琐碎的情况下,您的程序是几个文件,每个文件都需要一些stdlib模块(例如,os),这样可以节省程序开销,因为您的程序可以自行导入而无需重新导入所有重复的模块。

在这种情况下,Python第二次通过foo3知道foo3已被导入,因此不会再次导入。

实际上,它已加载两次,一次为__main__,一次为foo3

答案 1 :(得分:-1)

好吧,我得到了什么,我也在机器上运行了相同的代码。和我在一起以获得更好的理解!谢谢!

    def functionA():
        print("------------")
        from foo3 import functionB
        print("a2")
        functionB()
        print("a3")

    def functionB():
        print("b")
    if __name__ == "__main__":
        print("coming")
        print("t1")
        print("m1")
        functionA()
        print("m2")
        print("t2")

如果输入每个函数名称,则它将不执行main中的部分。而且它只会导入您期望的function_B,否则它将包括未在任何函数中定义的部分。 希望如此,您将获得所需的输出!谢谢。