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

装饰器中已声明变量却出现nonlocal绑定错误的原因咨询

为什么使用nonlocal会触发绑定错误?

先看你给出的代码:

def decorator(func):
    def returning():
        var = 1
        func()
        print(var)
    return(returning)

@decorator
def function():
    nonlocal var
    var = 5

function()

这个错误的核心是作用域的嵌套关系搞反了,咱们一步步理清楚:

  1. nonlocal的作用是什么?
    它是用来引用当前函数直接外层嵌套作用域里的变量,注意是「当前函数自己的外层」,不是随便哪个地方的变量。

  2. 你的代码里的作用域关系是怎样的?

  • returning()是decorator内部的嵌套函数,它的var是自己作用域里的局部变量。
  • 被装饰的function()是一个独立的顶级函数,它的外层作用域是全局作用域,和returning()的作用域没有任何嵌套关系!

当你调用function()时,其实是调用了returning(),在returning里执行func()也就是原来的function。这时候function里的nonlocal var会去寻找自己外层作用域(全局)里的var,但全局中根本没定义这个变量,自然就报错了——它完全不知道returning里有个var存在。

怎么解决这个问题?

如果想让function能修改returning里的var,得让两者的作用域产生关联,或者通过传递的方式让function能访问到这个变量,这里给两个简单的方案:

方案1:用可变对象传递(比如列表)

因为可变对象可以在函数内部修改其内容,不需要依赖作用域绑定:

def decorator(func):
    def returning():
        var = [1]  # 用列表包装变量
        func(var)
        print(var[0])
    return returning

@decorator
def function(var):
    var[0] = 5  # 修改列表里的元素

function()  # 输出:5

方案2:让函数返回修改后的值

把var作为参数传给function,再接收返回的新值:

def decorator(func):
    def returning():
        var = 1
        var = func(var)  # 接收function返回的新值
        print(var)
    return returning

@decorator
def function(var):
    return 5  # 返回修改后的值

function()  # 输出:5

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:52:36