与 Python 装饰器中的范围混淆

Confusion with scope in Python decorators

我正在尝试制作一个简单的 Python 装饰器,下面是我的用例的简化示例。

def decorator(x):
    def inner(f):
        if x == 2:
            x = 1
        return f
    return inner

@decorator(2)
def f():
    pass

但是我得到这个错误

if x == 2:
UnboundLocalError: local variable 'x' referenced before assignment

为什么 x 不可用?这很令人困惑,因为如果我使用 print(x) 而不是 if x == 2 它会按预期工作。

Python 无法确定 x 的实际范围,因此在它运行之前,在 inner 函数中它会引发 UnboundLocalError.

修复它的方法是稍微修改 inner 的参数,而不是:

    def inner(f):

使其成为:

    def inner(f, x=x):

那么你的代码就可以正常工作了。

或者您也可以使用 nonlocal,方法是在函数 inner.

的开头添加 nonlocal x
def inner(f):
    nonlocal x
    if x == 2:
        x = 1
    return f