You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中无if __name__ == "__main__"校验的自导入模块为何未无限递归?

foo3.py 代码执行逻辑解释

首先先给出你提到的无if __name__ == "__main__"校验的foo3.py示例代码:

# foo3.py
print("t1")

def functionA():
    print("a1")
    import foo3
    print("a2")

print("m1")
functionA()
print("m3")

核心前提

Python 有模块导入缓存机制:每个模块首次被导入时,会完整执行一次模块顶层代码,之后会将模块对象存入sys.modules字典缓存,后续再导入同一个模块时,直接返回缓存的模块对象,不会重复执行模块顶层代码,这就是不会触发无限递归的根本原因。

运行python3 foo3.py的完整执行顺序

  • 步骤1:当前foo3.py作为入口程序启动,此时对应模块的__name__值为__main__,从上到下执行顶层代码:
    1. 执行print("t1"),输出t1
    2. 完成functionA函数的定义(仅注册函数对象,不执行内部逻辑)
    3. 执行print("m1"),输出m1
    4. 调用functionA(),进入函数内部执行
  • 步骤2:进入__main__模块的functionA执行:
    1. 执行print("a1"),输出a1
    2. 执行import foo3:此时检查sys.modules,入口程序对应的模块名是__main__,不存在名为foo3的缓存,因此正式加载foo3.py作为名为foo3的模块,重新执行该文件的顶层代码
  • 步骤3:执行名为foo3的模块的顶层代码:
    1. 执行print("t1"),输出t1
    2. 完成foo3模块下functionA函数的定义(和__main__模块的functionA是独立的两个函数对象)
    3. 执行print("m1"),输出m1
    4. 调用foo3模块下的functionA(),进入该函数执行
  • 步骤4:进入foo3模块的functionA执行:
    1. 执行print("a1"),输出a1
    2. 执行import foo3:检查sys.modules,名为foo3的模块已经在步骤3加载并存入缓存,直接返回缓存对象,不重复执行foo3.py顶层代码
    3. 执行print("a2"),输出a2
    4. 该函数执行完毕,返回步骤3的调用点
    5. 执行print("m3"),输出m3
    6. foo3模块加载完成,返回步骤2的import foo3调用点
  • 步骤5:回到__main__模块的functionA继续执行:
    1. 执行print("a2"),输出a2
    2. 该函数执行完毕,返回步骤1的调用点
    3. 执行print("m3"),输出m3
    4. 整个程序执行结束

最终输出顺序为:

t1
m1
a1
t1
m1
a1
a2
m3
a2
m3

内容的提问来源于stack exchange,提问作者Milan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 01:15:04