python装饰器
装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
一般写法:
def how_much_time(func): def inner(): t_start = time.time() func() t_end = time.time() print("一共花费了{0}秒时间".format(t_end - t_start, )) return inner # 将增加的新功能代码以及被装饰函数运行代码func()一同打包返回,返回的是一个内部函数,这个被返回的函数就是装饰器 def sleep_5s(): time.sleep(5) print("%d秒结束了" % (5,)) sleep_5s = how_much_time(sleep_5s) sleep_5s()
语法糖写法:
def how_much_time(func): def inner(): t_start = time.time() func() t_end = time.time() print("一共花费了{0}秒时间".format(t_end - t_start, )) return inner @how_much_time # @how_much_time等价于sleep_5s = how_much_time(sleep_5s) def sleep_5s(): time.sleep(5) print("%d秒结束了" % (5,)) sleep_5s()
2.给某个函数加上多个装饰器
2.1给一个函数添加两个装饰器
# 为函数添加一个统计运行时长的功能以及日志记录功能 import time import threading def how_much_time(func): print("how_much_time函数开始了") def inner(): t_start = time.time() func() t_end = time.time() print("一共花费了{0}秒时间".format(t_end - t_start, )) return inner def mylog(func): print("mylog函数开始了") def inner_1(): print("start") func() print("end") return inner_1 @mylog @how_much_time # 等价于mylog(how_much_time(sleep_5s)) def sleep_5s(): time.sleep(5) print("%d秒结束了" % (5,)) if __name__ == '__main__': sleep_5s() #how_much_time函数开始了 #mylog函数开始了 #start #5秒结束了 #一共花费了5.012601613998413秒时间 #end
2.2当一个函数具有两个装饰器时的执行顺序
三,带参数装饰器的典型写法
四,类装饰器
类装饰器这个写法,主要思路就是返回一个增加了新功能的函数对象,只不过这个函数对象是一个类的实例对象。由于装饰器是可调用对象,所以必须在类里面实现__call__方法,这样由类生成的各种实例加上()就可以运行了。
1,不带参数的类装饰器
import time class Decorator: def __init__(self, func): self.func = func def defer_time(self): time.sleep(5) print("延时结束了") def __call__(self, *args, **kwargs): self.defer_time() self.func() @Decorator def f1(): print("延时之后我才开始执行") f1()
2,带参数的类装饰器
import time class Decorator: def __init__(self, func): self.func = func def defer_time(self,time_sec): time.sleep(time_sec) print(f"{time_sec}s延时结束了") def __call__(self, time): self.defer_time(time) self.func() @Decorator def f1(): print("延时之后我才开始执行") f1(5)