无法在装饰器内设置函数属性
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
并且主作用域中的 f
是 wrapper
函数对象。用不那么容易混淆的名字来说明:
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'
时,它会按预期工作。
我有这样的 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
并且主作用域中的 f
是 wrapper
函数对象。用不那么容易混淆的名字来说明:
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'
时,它会按预期工作。