一,装饰器的官方定义
装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
二,给某个函数加上一个装饰器
1,一般写法
import time
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,))
def sleep_6s():
time.sleep(6)
print("%d秒结束了" % (6,))
sleep_5s = how_much_time(sleep_5s)
# 因为sleep_5s函数的功能就是睡5秒钟,虽然增加了统计运行时间的功能,但是他本身功能没变(还是睡5秒钟),所以仍然用原来函数名接收增加功能了的自己
sleep_6s = how_much_time(sleep_6s)
t1 = threading.Thread(target=sleep_5s)
t2 = threading.Thread(target=sleep_6s)
t1.start()
t2.start()
# 5秒结束了
# 一共花费了5.014161109924316秒时间
# 6秒结束了
# 一共花费了6.011810302734375秒时间
2,语法糖写法
import time
import threading
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,))
@how_much_time
def sleep_6s():
time.sleep(6)
print("%d秒结束了" % (6,))
t1 = threading.Thread(target=sleep_5s)
t2 = threading.Thread(target=sleep_6s)
t1.start()
t2.start()
3,类装饰器
类装饰器这个写法,主要思路就是返回一个增加了新功能的函数对象,只不过这个函数对象是一个类的实例对象。由于装饰器是可调用对象,所以必须在类里面实现__call__方法,这样由类生成的各种实例加上()就可以运行了。
不带参数的类装饰器
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()
带参数的类装饰器
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)