Python 无法在装饰器内设置函数属性
我有这样一个Python代码:Python 无法在装饰器内设置函数属性,python,python-decorators,Python,Python Decorators,我有这样一个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'
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)
您可以找到就绪代码:
这段代码的问题是,我最终得到了
AttributeError:“function”对象没有属性“foo”
,尽管我使用了functools中的wrapps
decorator,它应该保留函数的属性范围。知道错误的原因是什么吗?您正在设置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()
def dec(f):
@包装(f)
def包装(*args,**kwargs):
f、 foo='foo'#dec
需要返回wrapper
notf
。您的装饰程序目前为no-op。只有在调用f()
时才会创建foo
属性。如果您希望在“装饰时间”创建它,请将该行移动到dec
,而不是wrapper
。修复了该问题,但它仍然不会消除根issue@deceze,请参阅问题中的更新代码。这个问题仍然存在,这不是deceze所建议的。你无缘无故地打了两次f(),我不同意你的看法,@deceze。这实际上就是functool
的wrapps
函数所做的。请参阅此代码-。使用和不使用wrapps装饰程序wrapps
进行游戏,确保wrapper
的签名与f
的签名相似。这并不能使它们成为同一个对象。decorator语法是sugar,用于bar=dec(bar)
bar
将是dec
返回的任何内容dec
返回wrapper
<代码>栏
是包装器
。您没有在该对象上设置属性,因此它不会显示在那里。