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

Python变量作用域LEGB规则疑问:为何找不到pass_a中的变量b?

理解Python的静态作用域(纠正LEGB规则的常见误解)

嘿,这个问题是对Python作用域规则的典型误解——咱们先把你的代码清晰列出来,再一步步拆解问题所在:

你的代码及报错

def fun():
    print b

def pass_a(b):
    fun()

pass_a(2)

执行后触发报错:

NameError: global name 'b' is not defined

问题出在哪?你对LEGB的理解差了关键一点

你提到的LEGB(Local→Enclosing→Global→Built-in)查找顺序是对的,但这里的核心误区是:Python采用的是「词法作用域(静态作用域)」,不是动态作用域。

简单说,函数的作用域是在定义的时候确定的,而不是在调用的时候。咱们对应你的例子来看:

  • fun函数是直接定义在全局作用域中的,它的「Enclosing(嵌套)作用域」就是全局作用域,和pass_a函数没有嵌套关系
  • 当你在pass_a里调用fun时,fun并不会去pass_a的局部作用域里找b——因为它的作用域在定义时就已经绑定到了全局,不会随着调用位置变化而改变

怎么修改才能让代码符合你的预期?

如果想让fun能访问pass_a中的b,需要把fun嵌套定义在pass_a内部,这样它的Enclosing作用域就会绑定到pass_a的局部作用域:

def pass_a(b):
    def fun():
        print b
    fun()

pass_a(2)  # 此时会正常输出2

这时候调用fun时,LEGB查找就会先在fun的Local作用域找b(找不到),然后去Enclosing作用域(也就是pass_a的局部作用域)找到b,顺利执行。

再划个重点

LEGB规则里的「Enclosing作用域」,指的是函数定义阶段包裹它的外层函数作用域,而不是函数调用阶段所在的栈帧作用域。Python的作用域绑定是静态的,这是它和部分动态作用域语言的核心区别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:50:15