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

为何在异常处理中导入time模块后仍触发RecursionError?

为什么这段Python代码会触发RecursionError?

先贴出你的代码:

def s():
    try:
        time.sleep(1)
    except NameError:
        import time
        s()


for i in range(10):
    s()
    print(i)

按照你的预期,这段代码本不该触发RecursionError——正常流程应该是第一次调用s()触发NameError,导入time后递归调用s()完成休眠,之后的循环调用都直接执行休眠。但如果你确实碰到了递归错误,多半是以下原因:

  1. 隐性命名冲突:如果脚本其他地方有time变量的赋值(比如time = 5),会覆盖全局的time模块引用,导致每次调用s()都触发NameError,进而无限递归调用s(),最终触发RecursionError。
  2. 作用域误解:虽然import time会把模块导入全局命名空间,但极少数情况下,递归调用的s()可能因为解释器的局部作用域缓存,无法立即找到全局的time,导致再次进入except块递归。

满足你需求的正确写法

你需要的是仅在函数首次调用时导入time,且仅在未导入时执行导入,给你几种靠谱的实现方式:

方式一:显式声明全局变量,避免递归

def s():
    global time
    try:
        time.sleep(1)
    except NameError:
        import time
        time.sleep(1)


for i in range(10):
    s()
    print(i)

用global time明确指定使用全局的time引用,导入后直接执行休眠,不需要递归调用,避免栈消耗。

方式二:给函数加导入标记(推荐)

def s():
    if not hasattr(s, '_time_loaded'):
        import time
        s._time_loaded = True
    time.sleep(1)


for i in range(10):
    s()
    print(i)

通过给函数对象添加一个属性标记,确保time只会在第一次调用s()时导入一次,后续调用直接使用已导入的模块,逻辑清晰且高效。

方式三:简化try-except逻辑

def s():
    try:
        time.sleep(1)
    except NameError:
        import time
        time.sleep(1)  # 导入后直接执行,不用递归


for i in range(10):
    s()
    print(i)

最接近你的原代码,但去掉了递归调用,导入后直接完成休眠操作,避免不必要的函数栈嵌套。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:24:59