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

Python解释器遇错即停为何生成两种不同错误信息?

为什么两个场景会出现不同的运行时错误?

这问题问到点子上了!很多人会误以为Python是完全逐行执行、遇到错误就立刻停止,但实际上Python在处理函数的时候,会先在编译阶段做作用域分析,这就是两个场景错误不同的核心原因。

先明确两个错误的含义

  • NameError:表示你引用的变量名在当前及所有外层可访问的作用域中都不存在。
  • UnboundLocalError:这是NameError的子类,专门用于这种情况:变量被标记为局部变量,但在赋值之前就被引用了。

场景1:NameError的原因

看场景1的代码:

def a():
    print(aa+bb)
#aa=10
#bb=20
print(a())
  1. 编译函数a的时候,Python扫描函数体,发现里面没有对aa或bb的赋值操作,所以会把这两个变量标记为“需要从外层作用域查找”。
  2. 当调用a()时,Python先在函数a的局部作用域找aa,找不到就去全局作用域找——但全局作用域里aa和bb被注释掉了,根本不存在。
  3. 所以Python抛出NameError:它找不到aa这个名字的任何定义。

场景2:UnboundLocalError的原因

这里要先提一句:你给出的场景2代码看起来有点矛盾——如果只是单纯的print(aa+bb),全局又定义了aa=10和bb=20,那运行应该输出30和None,不会报错。推测你可能是笔误,函数内部其实有对aa的赋值操作(比如aa = aa + bb,或者在print之后有aa = 30这类代码),才会触发UnboundLocalError。

假设修正后的场景2代码是这样(符合错误信息的情况):

def a():
    print(aa+bb)
    aa = 30  # 这里有对aa的赋值操作
aa=10
bb=20
print(a())

现在解释错误原因:

  1. 编译函数a的时候,Python扫描到函数内部有aa = 30这个赋值操作,立刻把aa标记为局部变量——不管这个赋值语句在函数的哪个位置,只要存在,整个函数里的aa都会被视为局部变量。
  2. 当调用a()时,执行print(aa+bb),Python会去局部作用域找aa,但此时aa还没有被赋值(赋值语句在print之后),所以抛出UnboundLocalError:局部变量aa在赋值前就被引用了。
  3. 至于bb,因为函数内部没有对它的赋值,Python会去全局作用域找到bb=20,所以不会报错在bb上。

总结一下核心规则

Python的变量作用域遵循“LEGB”规则,但关键是:

  • 只要函数内部有对变量的赋值操作,这个变量就会被视为局部变量,不管赋值语句在代码的哪个位置。
  • 如果函数内部没有赋值操作,Python会依次从局部、外层嵌套、全局、内置作用域查找变量。
  • 编译阶段的作用域标记,是导致这两个错误不同的根本原因,而不是单纯的“逐行执行遇错即停”。

内容的提问来源于stack exchange,提问作者Deepak Tatyaji Ahire

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:46:03