带参数的装饰器
装饰器使用过程中,如果需要一个参数来判断装饰器是否启用时,就需要传入一个参数,来判断是否启用。
目前装饰器,传输函数名给外部函数做参数,内部函数参数用做调用函数的参数,无法实现参数的传递。
因此,需要在加一层嵌套,来实现参数的传入,装饰器最多三层!!!
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()
多个装饰器装饰一个函数,函数前,从最外层装饰器,执行到最内层 → 执行函数 → 在从最内层开始,往外执行