python变量作用域按l→e→g→b顺序查找:局部(函数内赋值,默认仅函数执行时存在,无块级作用域)、嵌套(内层函数可读外层变量,修改需nonlocal)、全局(模块级,用global声明可读写)、内置(如len/print,应避免覆盖)。

函数内部变量的可见性不是由“谁调用了它”决定的,而是由代码在源文件中嵌套的位置静态确定的。Python 按照 L → E → G → B 的固定顺序查找变量:先找局部(Local),再找外层嵌套函数(Enclosing),然后是全局(Global),最后是内置(Built-in)。
局部作用域:函数体内自成一格
在函数定义体内部直接赋值的变量,默认属于局部作用域。它只在该函数执行期间存在,函数返回后即销毁。
- 即使语句块如
if或for内定义变量,也不产生新作用域——Python 没有块级作用域 - 只要出现赋值语句(如
x = 10),Python 就认定x是当前函数的局部变量,哪怕赋值写在条件分支里 - 若想读取同名全局变量又不创建局部变量,只能靠
global显式声明;否则未赋值前就引用会触发UnboundLocalError
嵌套作用域:外层函数变量可被内层函数“记住”
当一个函数定义在另一个函数内部时,内层函数能访问外层函数中定义的变量,这种关系构成闭包的基础。
- 外层函数的局部变量对内层函数来说是“非局部”(nonlocal)的,但默认只读;要修改必须用
nonlocal声明 -
nonlocal只能向上查找一层或若干层嵌套函数中的变量,不能跳过一层去改更外层或全局变量 - 如果内层函数中重新赋值同名变量,且未加
nonlocal,就会创建新的局部变量,不会影响外层
全局与内置:最外层的两个保障层
模块顶层定义的变量属于全局作用域,整个模块内都可读(除非被同名局部变量遮蔽);而像 len、print 这类内置名称,则始终可用,无需导入。
-
global关键字用于在函数内明确告诉解释器:“我要操作的是模块级的那个变量”,允许读写 - 注意:在嵌套函数中使用
global,修改的是模块变量,不是外层函数的局部变量 - 内置作用域几乎不会被覆盖,但技术上可以——比如在全局作用域执行
len = lambda x: 42,后续调用len()就会出错;应避免这类操作











