无法在装饰器内设置函数属性

Cannot set function attribute inside a decorator

我有这样的 Python 代码:

from functools import wraps

def dec(f): 
    
    @wraps(f)
    def wrapper(*args, **kwargs):
        f.foo = 'foo'
        value = f()
        f.foo = 'foo'
        return value
    return wrapper

@dec
def f():
    print('Hello, f')

f()
print(f.foo)

您可以找到现成的代码here:

此代码的问题是我最终得到了 AttributeError: 'function' object has no attribute 'foo',尽管我使用了 functools 中的 wraps 装饰器,它应该保留函数的属性范围。知道错误的原因是什么吗?

您正在 f 上设置属性,但您返回的是 wrapper 并且主作用域中的 fwrapper 函数对象。用不那么容易混淆的名字来说明:

def dec(f): 
    @wraps(f)
    def wrapper(*args, **kwargs):
        f.foo = 'foo'  # <-- this is the original bar function
        value = f()
        return value

    return wrapper

@dec
def bar():
    print('Hello, f')

bar()  # <-- this is wrapper()

当您将代码更改为 wrapper.foo = 'foo' 时,它会按预期工作。