Python 3.9: 定义了 2 个函数装饰器。 目标是检测函数是否应用了 0、1 或 2 个装饰器。
为什么下面的代码为第二个装饰器返回“False”?
def decorator1(f):
def wrapped(*args, **kwargs):
f(*args, **kwargs)
wrapped.dec1 = True
return wrapped
def decorator2(f):
def wrapped(*args, **kwargs):
f(*args, **kwargs)
wrapped.dec2 = True
return wrapped
@decorator1
@decorator2
def myfunc():
print(f"running myfunc")
if __name__ == "__main__":
myfunc()
print(f"myfunc has decorator1: {getattr(myfunc, 'dec1', False)}")
print(f"myfunc has decorator2: {getattr(myfunc, 'dec2', False)}")
结果:
running myfunc
myfunc has decorator1: True
myfunc has decorator2: False
此代码:
@decorator1
@decorator2
def myfunc():
print(f"running myfunc")
相当于:
def myfunc():
print('running myfunc')
myfunc = decorator2(myfunc)
myfunc = decorator1(myfunc)
请记住,您将这些动态属性添加到
wrapped
函数中。包装的函数是这两个装饰器中的两个不同的对象:
myfunc = decorator2(myfunc)
print(myfunc) # <function decorator2.<locals>.wrapped at 0x1028456c0>
myfunc = decorator1(myfunc)
print(myfunc) # <function decorator1.<locals>.wrapped at 0x102845760>
堆叠装饰器后,您可以预期
decorator1.<locals>.wrapped
具有 dec1
,但它没有 dec2
。就在decorator2.<locals>.wrapped
:
def decorator1(f):
def wrapped(*args, **kwargs):
return f(*args, **kwargs)
wrapped.dec1 = True
return wrapped
def decorator2(f):
def wrapped(*args, **kwargs):
return f(*args, **kwargs)
wrapped.dec2 = True
return wrapped
def myfunc():
print('running myfunc')
myfunc = decorator2(myfunc)
myfunc = decorator1(myfunc)
print(f"myfunc has decorator1: {getattr(myfunc, 'dec1', False)}")
print(f"myfunc has decorator2: {getattr(myfunc.__closure__[0].cell_contents, 'dec2', False)}")