Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么这不是一个无限循环?_Python_Namespaces_Main_Python Module - Fatal编程技术网

Python 为什么这不是一个无限循环?

Python 为什么这不是一个无限循环?,python,namespaces,main,python-module,Python,Namespaces,Main,Python Module,此代码是从此线程中的答案中提取的 我认为代码的执行方式如下(当作为主python3foo3.py执行时): 1.打印t1 2.打印m1 3.输入函数并打印a1 4.从foo3导入functionB,从而再次运行foo3。返回到步骤1 你能帮我更正我的分析吗?它不会“再次运行foo3”,它会再次运行foo3.py脚本。第一次运行foo3.py是为了生成模块\uuuu main\uuuu,第二次是为了生成模块foo3.py 这种行为实际上(几乎)就像您有一个名为\uuuu main\uuuuuuuu

此代码是从此线程中的答案中提取的

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

它不会“再次运行
foo3
”,它会再次运行
foo3.py
脚本。第一次运行
foo3.py
是为了生成模块
\uuuu main\uuuu
,第二次是为了生成模块
foo3.py

这种行为实际上(几乎)就像您有一个名为
\uuuu main\uuuuuuuuuuuuuuuuuuuuuuupy
的文件和另一个名为
foo3.py
的文件,它们的内容完全相同,然后运行
python\uuuuuu main\uuuuuuuuuuuuuuuuupy
。这就是正在发生的事情

只是Python伪造了它,使程序看起来好像是从名为
\uuuu main\uuuu.py
的脚本启动的,而不管实际的Python文件是什么。唯一与此相反的迹象是
\uuuuu file\uuuu
会显示实际脚本的文件名,即
/spam/ham/eggs/foo3.py


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

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

它最终执行第二次导入。这次
sys.modules
中有
foo3
,因此导入不会创建或加载更多脚本,只会返回已加载的模块

要获得“无限”循环,您可以在再次导入
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
[…]
文件“../foo3.py”,第7行,在函数中
从foo3导入函数b
文件“../foo3.py”,第17行,在
函数()
文件“../foo3.py”,第7行,在函数中
从foo3导入函数b
RuntimeError:调用Python对象时超出了最大递归深度

感谢您的清晰解释!如果我想更多地了解python的工作原理并更好地掌握该语言,您是否建议提供一些好的资源?@PrashanthRavichandar阅读源代码将是一个不错的选择——尽管这可能有点类似于不带任何装备跳入河中并尝试学习游泳。只要我的两分钱。阅读源代码会导致货物崇拜,也就是说,你在没有充分理解的情况下重复别人代码中看到的模式。对于Python来说,官方的Python教程、PEP和各种书籍都很好。
  [....]
  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