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

Python嵌套异常使用同名变量时为何抛出NameError?

Python嵌套try/except中同名异常变量引发NameError的原因与解决方法

问题场景

以下是复现问题的最小示例代码:

try:
    1 / 0
except ZeroDivisionError as error:
    try:
        [1, 2, 3][3]
    except IndexError as error:
        pass
    print("The last error was:", error)

实际运行后会抛出NameError:

Traceback (most recent call last):
  File "/home/sorenmulli/lala.py", line 2, in <module>
    1 / 0
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/sorenmulli/lala.py", line 8, in <module>
    print("The last error was:", error)
NameError: name 'error' is not defined

而预期输出应为:

The last error was: list index out of range.

通过以下修改可得到预期结果:

try:
    1 / 0
except ZeroDivisionError as error_tmp:
    error = error_tmp
    try:
        [1, 2, 3][3]
    except IndexError as error_tmp:
        error = error_tmp
    print("The last error was:", error)

原因解析

核心原因是:Python在except块执行完毕后,会自动销毁该块内通过as绑定的异常变量。这个设计是为了避免异常对象因被当前栈帧引用而无法被垃圾回收,防止内存泄漏。

具体到你的代码逻辑:

  1. 外层except ZeroDivisionError as error:error绑定了除零异常对象,作用域为外层except块。
  2. 内层触发IndexError后,except IndexError as error中的error是内层except块的局部变量,会遮蔽外层的error,并重新绑定索引异常对象。
  3. 内层except块执行完毕,Python自动销毁这个error变量。由于内层的error已经覆盖了外层的同名变量绑定,后续print语句访问error时,该变量已不存在,因此抛出NameError。

解决方法

你的修正思路是可行的:将异常变量赋值给外层作用域的变量,避开except块的自动销毁机制。另外也可以直接用不同的变量名区分内外层异常,代码可读性更高:

try:
    1 / 0
except ZeroDivisionError as outer_err:
    current_err = outer_err
    try:
        [1, 2, 3][3]
    except IndexError as inner_err:
        current_err = inner_err
    print("The last error was:", current_err)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:01:57