python3装饰器-进阶
一、wraps
作用:优化装饰器
from functools import wraps # 导入wraps def wrapper(f): @wraps(f) # wraps的语法糖 def inner(*args, **kwargs): ret = f(*args, **kwargs) return ret return inner @wrapper def f1(): print("Hello, World!") return 'Hi' res = f1() print(res) print(f1.__name__) # 查看字符串格式的函数名,打印的函数名inner->f1
二、带参数的装饰器
实质:嵌套调用,三层嵌套函数
from functools import wraps import time flag = True def wrapper_out(is_flage): def wrapper(func): """ flag为True时函数被装饰器装饰 flag为FLASE时函数正常被调用 :param func: :return: """ @wraps(func) def inner(*args, **kwargs): # 聚合 if is_flage: start = time.time() ret = func(*args, **kwargs) # 打散 end = time.time() print(end-start) return ret else: ret = func(*args, **kwargs) return ret return inner return wrapper @wrapper_out(flag) # @wrapper_out()->@wrapper->f1=wrapper(f1) 调用wrapper_out(flag)函数,return wrapper def f1(): time.sleep(1) print("Hello, World") return 'joker' ret = f1() print(ret)
三、多个装饰器装饰一个函数
from functools import wraps def wrapper1(func): # func->f1 @wraps(func) def inner1(*args, **kwargs): print("wrapper1,before") # 2 ret = func(*args, **kwargs) # 3, f1() print("wrapper1,after") # 4 return ret # ret is f1()的返回值,现在是执行inner1()的返回值 return inner1 def wrapper2(func): # func->inner1 @wraps(func) def inner2(*args, **kwargs): print("wrapper2,before") # 1 ret = func(*args, **kwargs) # inner1() print("wrapper2,after") # 5, 执行完inner1() return ret # ret is inner1()的返回值即f1()的返回值,现在是执行inner2()的返回值 return inner2 @wrapper2 # f1=wrapper2(inner1) @wrapper1 # f1=wrapper1(f1)->f1=inner1 def f1(a): print("Hello") return a """ f1指向inner2的内存地址,f1()->inner2(),f1()的返回值是inner2()的返回值,也就是f1()函数自身的返回值 """ ret = f1(2) print(ret) """ 结果: wrapper2,before wrapper1,before Hello wrapper1,after wrapper2,after 2 """
现象: