我试图通过以下代码了解如何在一个函数上使用两个装饰器:
def fxn(func):
print("fxn_outer 1")
def fxn_inner(*args, **kwargs):
print("fxn_inner 1")
return fxn_inner
def fxn2(func):
print("fxn_outer 2")
def fxn_inner2(*args, **kwargs):
print("fxn_inner 2")
return fxn_inner2
@fxn
@fxn2
def fxn3 (a, b):
print(a + b)
fxn3(1, 2)
我很困惑为什么在上面的代码中执行了fxn_inner,而fxn_inner2却没有。
输出是:
fxn_outer 2
fxn_outer 1
fxn_inner 1
当我期望以下输出时:
fxn_outer 2
fxn_outer 1
fxn_inner 1
fxn_inner 2
为什么当我同时调用两个包装函数时只执行其中一个?
请您参考如下方法:
装饰器只是调用函数和重新分配名称的语法糖,所以你所做的等同于:
fxn3 = fxn2(fxn3)
fxn3 = fxn(fxn3)
fxn3(1, 2)
那么发生了什么?第一次赋值后,你有 fxn3 == fxn2_inner。 在第二行之后你有 fxn3 == fxn_inner。
但是fxn(和fxn_inner)的定义他们只是丢掉了参数func!因此,当您调用 fxn3(1,2) == fxn_inner(1, 2) 时,您看不到它被调用。
如果你想调用原始函数,你应该在 *_inner 函数中调用 func:
def fxn(func):
print("fxn_outer 1")
def fxn_inner(*args, **kwargs):
print("fxn_inner 1")
return func(*args, **kwargs)
return fxn_inner
def fxn2(func):
print("fxn_outer 2")
def fxn_inner2(*args, **kwargs):
print("fxn_inner 2")
return func(*args, **kwargs)
return fxn_inner2
