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

递归函数try-except块变量声明异常:两段代码为何表现不同?

嵌套函数与递归中的变量作用域差异解析

先看你给出的代码示例:

可正常运行的嵌套函数代码

class c:
    def __init__(self, a):
        self.n=a
def a():
    t=c(5)
    def b():
        print(t.n)
    b()

这段代码能正常打印5,核心原因是嵌套函数的闭包特性:

  • 函数a内部定义了局部变量t,嵌套函数b在a的作用域内被定义,因此b可以捕获并访问a作用域中的t。当调用b()时,直接使用a里已经初始化好的t,自然能正常打印。

无法打印的递归函数代码

def d():
    try:
        t
        print(t.n)
    except:
        t=c(5)
        d()

这段代码永远不会执行到print(t.n),问题出在递归的栈帧独立性:

  • 第一次调用d()时,进入try块尝试访问t,此时当前栈帧的局部作用域中没有t,触发except块。
  • 在当前栈帧里定义t=c(5)后,递归调用d()——这会创建一个全新的函数栈帧,新栈帧的局部作用域和之前的完全独立,里面并没有t的定义。
  • 新的d()调用又会重复上述过程:try块找不到t,进入except定义t,再递归调用d(),形成无限递归,永远没有栈帧能走到print(t.n)这一步。

两者的核心差异

  • 嵌套函数共享外层函数的作用域,b能直接复用a里的t;
  • 递归的每次调用都是独立的函数栈帧,每个栈帧的局部变量互不共享,后一次调用无法访问前一次栈帧里定义的t。

如果要让递归版本正常工作,你需要让t处于所有递归调用的共享作用域,比如用函数默认参数传递:

def d(t=None):
    if t is None:
        t=c(5)
        d(t)
    else:
        print(t.n)

这样第一次调用d()时初始化t,递归调用时把t传递下去,就能正常打印5了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:15:48