我想编写一个装饰器来显示装饰函数的真实名称,但是当我以这种方式编写时会出现问题。
from functools import update_wrapper
def decorator(d):
def _decorator(f):
update_wrapper(d(f), f)
return d(f)
return _decorator
@decorator
def add2(f):
def _add2(x,y):
return f(x,y)*2
return _add2
@add2
def add(x,y): return x+y
如果我想获得add(x,y)的名称,它会显示如下:
>>>print add.__name__
_add2
但是,如果我对func装饰器做了一点改动:
def decorator(d):
def _decorator(f):
return update_wrapper(d(f), f)
return _decorator
结果是正确的:
>>>print add.__name__
add
我真的很困惑。在我看来,这不应该产生这样的差异,因为它们几乎是一样的。
答案 0 :(得分:0)
您致电d(f)
两次,每个人都会创建一个新的包装函数对象;这些是独立的新副本。您只需将update_wrapper()
应用于第一个结果并返回第二个结果。
将其称为一次:
def decorator(d):
def _decorator(f):
wrapper = d(f)
update_wrapper(wrapper, f)
return wrapper
return _decorator