必须用global:在函数内对已存在的模块级变量赋值且需影响全局时;必须用nonlocal:在嵌套函数中修改外层函数的局部变量且该变量非全局也非本层局部时。

global 用于改模块级变量,nonlocal 用于改外层函数的局部变量;写错一个,轻则值不更新,重则直接报 UnboundLocalError 或 SyntaxError。
什么时候必须用 global?
当你在函数内对一个**已经存在的模块级变量**做赋值(=、+= 等),且希望这个修改影响到全局作用域时,必须加 global 声明。
常见错误现象:
- 没加
global就直接x += 1→ 报UnboundLocalError: local variable 'x' referenced before assignment - 误以为读取全局变量也要加
global→ 其实只读不写完全不需要
实操建议:
- 只在「要写入」且该变量定义在模块顶层(即函数外部)时才用
global -
global声明本身不创建变量,但global x; x = 5会创建全局x(如果之前不存在) - 不要在同一个函数里对同一变量混用
global和nonlocal,Python 直接拒绝编译
什么时候必须用 nonlocal?
当你在嵌套函数(比如 inner() 在 outer() 里面)中,想修改**外层函数定义的局部变量**,且这个变量既不是当前函数的局部变量,也不是全局变量时,必须用 nonlocal。
常见错误现象:
- 没加
nonlocal就赋值 → Python 默认把它当成本地新变量,外层变量不变 - 外层函数没定义该变量,却写了
nonlocal x→ 报SyntaxError: no binding for nonlocal 'x' found - 最外层函数(即模块顶层)里写
nonlocal x→ 直接语法错误,nonlocal只允许出现在嵌套函数中
实操建议:
-
nonlocal查找是「就近向外」:从直接外层开始,逐层往上找,不跨过函数去查全局 - 可以一次声明多个变量:
nonlocal a, b, c - 如果外层变量被
global声明过,nonlocal就找不到它 —— 它只认「未被 global 绑定的外层局部变量」
global 和 nonlocal 能不能共存?
能,但不能在同一作用域里针对同一个变量。它们是互斥的绑定指令。
典型场景是多层嵌套时分层控制:
- 最外层函数定义
counter = 0 - 中间函数用
nonlocal counter修改它 - 最内层函数如果想改模块级配置(比如
DEBUG = True),就用global DEBUG
注意点:
- Python 不允许在同一个函数里同时出现
global x和nonlocal x - 一旦某层用了
global x,所有内层函数再想操作x,都只能走全局路径,不能再用nonlocal回溯到更早的局部定义 - 这种混合使用容易让变量流向变模糊,建议用类或参数显式传递替代
最容易被忽略的细节
很多人卡在「为什么明明写了 nonlocal 还报错?」—— 根本原因常是:外层函数里那个变量,其实已经被 global 声明过了,或者压根没在那个外层函数里赋过值(只是读了全局同名变量)。
另一个隐形坑是闭包捕获:如果外层函数返回了内层函数,而内层用了 nonlocal,那这个变量不会被释放,形成活跃引用。调试时用 inner.__closure__ 可以验证是否真绑定了外层变量。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











