带参数的装饰器
装饰器使用过程中,如果需要一个参数来判断装饰器是否启用时,就需要传入一个参数,来判断是否启用。
目前装饰器,传输函数名给外部函数做参数,内部函数参数用做调用函数的参数,无法实现参数的传递。
因此,需要在加一层嵌套,来实现参数的传入,装饰器最多三层!!!
import time
from functools import wraps
FLAG = True
def out_warpper(flag):
def warpper(f):
@wraps(f)
def w_in():
if flag:
print("this is warp!")
ret = f()
else:
ret = f()
return ret
return w_in
return warpper
# out_warpper = out_warpper(FLAG) → out_warpper = warpper
# func1 = warpper(func1) → func1 = w_in
@out_warpper(FLAG) # func1
def func1():
time.sleep(1)
print("this is func1")
@out_warpper(FLAG)
def func2():
time.sleep(1)
print("this is func2")
func1()
func2()
三层时,先执行@符号后的行数,即out_warpper = out_warpper(FLAG) ,返回 out_warpper = warpper,闭包函数,存下了变量flag。
在执行@函数名,func1 = warpper(func1) ,返回func1 = w_in,从而实现了传参数的装饰器。
多个装饰器装饰一个函数
def warper1(f):
def inner():
print("begin do inner1!")
f()
print("after go inner1!")
return inner
def warper2(f):
def inner():
print("begin do inner2!")
f()
print("after go inner2!")
return inner
def warper3(f):
def inner():
print("begin do inner3!")
f()
print("after go inner3!")
return inner
@warper3
@warper2
@warper1
def func():
print("this is func")
func()

多个装饰器装饰一个函数,函数前,从最外层装饰器,执行到最内层 → 执行函数 → 在从最内层开始,往外执行