python变量查找遵循legb规则:local→enclosing→global→built-in。局部作用域含函数内变量;嵌套外层作用域支持闭包与nonlocal;全局作用域需global修改;内置作用域含len等预定义名,覆盖后可用del恢复。

Python 变量查找遵循 LEGB 规则,即按 Local(局部)→ Enclosing(嵌套外层)→ Global(全局)→ Built-in(内置)的顺序依次搜索变量名。
Local(局部作用域)
函数内部定义的变量,包括参数和函数内赋值的变量,只在该函数内有效。每次调用函数都会新建一个局部作用域。
- 函数中对变量赋值(如
x = 10),默认视为创建局部变量,除非显式声明global或nonlocal - 读取变量时,若未赋值过,会继续向上一级作用域查找;但一旦在函数内有赋值,整个函数体都将其视为局部变量(即使赋值语句在
if中且未执行)
Enclosing(嵌套外层作用域)
指外层嵌套函数的作用域,仅在闭包(closure)场景下生效。内层函数可以读取外层函数的变量,但不能直接修改(需用 nonlocal 声明)。
- 外层函数返回内层函数时,内层函数携带对外层变量的引用,构成闭包
-
nonlocal x告诉 Python:这个x来自最近的外层非全局作用域,允许读写 - 没有
nonlocal时,对嵌套变量赋值会创建新的局部变量,不影响外层
Global(全局作用域)
模块层级(即文件顶层)定义的变量属于全局作用域,在整个模块内可见。函数内读取全局变量无需声明,但修改必须加 global 关键字。
立即学习“Python免费学习笔记(深入)”;
-
global x表示“接下来对x的赋值操作作用于模块级变量” - 不加
global直接写x = ...,会在函数内新建同名局部变量 - 导入的模块名、类名、函数名默认也是全局变量
Built-in(内置作用域)
Python 预定义的名称,如 len、print、int、Exception 等,位于 builtins 模块中,所有作用域都可直接使用。
- 如果在全局或局部作用域中定义了同名变量(如
len = "hello"),会覆盖内置名称,导致后续调用出错 - 可通过
del len删除局部/全局同名变量,恢复对内置len的访问 - 一般不建议覆盖内置名称,容易引发隐蔽错误
理解 LEGB 不是为了死记顺序,而是看清变量“从哪来、往哪写”。遇到 UnboundLocalError 或名字被意外覆盖,顺着这四个层级排查通常就能定位问题。










