为何在异常处理中导入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()完成休眠,之后的循环调用都直接执行休眠。但如果你确实碰到了递归错误,多半是以下原因:
- 隐性命名冲突:如果脚本其他地方有
time变量的赋值(比如time = 5),会覆盖全局的time模块引用,导致每次调用s()都触发NameError,进而无限递归调用s(),最终触发RecursionError。 - 作用域误解:虽然
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
相关产品推荐
相关产品推荐

