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

Python高阶函数何时需要使用nonlocal关键字?

Python高阶函数开发中nonlocal关键字的使用规则

核心判断逻辑完全基于Python的静态作用域规则,和变量是不是在函数外部调用没有关系:

  • 当你在嵌套定义的内层函数中,需要对外层非全局作用域的变量做重新赋值操作时,必须使用nonlocal声明该变量,否则Python会默认将其识别为当前内层函数的局部变量,触发变量未定义的报错。
  • 如果只是读取外层作用域的变量值,从来不对变量本身做重新赋值,不需要加任何声明,Python会自动沿着作用域链向上查找匹配的变量。

为什么代码1必须加nonlocal声明

代码1的内层say函数中存在对previous_score的直接赋值语句:

previous_score = max(previous_score, current_score)

如果没有nonlocal声明,Python解析函数的时候,会把所有出现在赋值符号左边的变量判定为当前函数的局部变量。这时候执行到赋值语句右边取previous_score值的时候,这个局部变量还没完成赋值,就会抛出UnboundLocalError: local variable 'previous_score' referenced before assignment错误,代码根本无法运行。
加上nonlocal previous_score后,Python就会明确:这个变量不属于当前say函数的局部作用域,去外层announce_max的作用域中查找对应变量,赋值操作也是修改外层作用域的变量值,而非新建局部变量,逻辑才能正常跑通。

为什么代码2不需要nonlocal就能运行

看代码2的say函数逻辑,全程没有对previous_score做任何赋值操作,所有用到这个变量的地方都是单纯读取它的值:

# 只是读取previous_score的值传给max计算,没有修改变量本身
print(max(previous_score, current_score))
# 同样是读值计算,把结果作为参数传给新的announce_max调用,没有给previous_score赋值
return announce_max(max(previous_score, current_score))

这种只读不写的场景下,Python不会把previous_score识别为局部变量,会自动向上找到外层announce_max函数的参数previous_score取值,因此不需要额外声明就能正常运行。


常见误区提醒:不要混淆「修改可变对象内部内容」和「给变量重新赋值」。比如外层变量是一个字典d = {},内层写d['score'] = 1是修改字典内部的键值对,不是给d变量本身重新赋值,不需要加nonlocal;但如果内层写d = {'score':1},就是给变量重新赋值,必须加nonlocal声明才能修改外层的d变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:27:17