第十一天 18/5/11 装饰器
一、什么是装饰器?
装饰器本质上就是一个 python 函数,它可以让其他函数在不需要做出任何代码变动的前提下,额外增加功能,装饰器的返回值也是一个函数对象。
应用场景:插入日志,性能测试,事务处理,缓存等场景。
二、装饰器的形成过程。
我有一需求,我想让你测试这个函数的执行时间,在不改变这个代码的情况下:
def login(): print('游戏开始') import time # 导入时间模块 start_time = time.time() # 记录开始时间 login() # 开始函数 end_time = time.time() # 记录终止时间 print('此函数所用时间为%s' % (end_time - start_time)) 游戏开始 此函数所用时间为0.0第一版本【不是函数,雏形】
import time # 导入时间模块 def login(): time.sleep(0.3) # 停顿时间0.3 print('游戏开始') def timmer(): start_time = time.time() # 记录开始时间 login() # 开始函数 end_time = time.time() # 记录终止时间 print('此函数所用时间为%s' % (end_time - start_time)) timmer()装饰器 1.0 版
但是,如果有多个函数,我都想让你进行测试他们的执行时间,这 1.0 版是不是都得做出改变呢?
import time # 导入时间模块 def login(): # 第一函数 time.sleep(0.3) # 停顿时间0.3 print('游戏开始') def dier(): # 第二函数 time.sleep(0.4) print('准备好了么') def timmer(f): start_time = time.time() # 记录开始时间 f() # 开始函数 end_time = time.time() # 记录终止时间 print('此函数所用时间为%s' % (end_time - start_time)) timmer(login) timmer(dier) # 改变了我原来执行函数的执行方式1.1 版【改变了我原来执行函数的执行方式 】
import time # 导入时间模块 def login(): # 第一函数 time.sleep(0.3) # 停顿时间0.3 print('游戏开始') def timmer(f): start_time = time.time() # 记录开始时间 f() # 开始函数 end_time = time.time() # 记录终止时间 print('此函数所用时间为%s' % (end_time - start_time)) f1 = login # 设变量 f1 将login 赋值给 f1 login = timmer # 【新设】变量 login 将 timmer 赋值给 login login(f1) # timmer(login)1.2版,虽然还原了函数的执行方式,但增加了变量
import time # 导入时间模块 def login(): # 第一函数 time.sleep(0.3) # 停顿时间0.3 print('游戏开始') def timmer(f): def inner(): start_time = time.time() # 记录开始时间 f() # 开始函数 login end_time = time.time() # 记录终止时间 print('此函数所用时间为%s' % (end_time - start_time)) return inner login = timmer(login) # login = inner login() # 执行函数 inner()1.3版 利用赋值进行改变
在python中有个更简单的方法:语法糖:F1 = X1(F1)——> @X1
import time # 导入时间模块 def timmer(f): def inner(): start_time = time.time() # 记录开始时间 f() # 开始函数 login end_time = time.time() # 记录终止时间 print('此函数所用时间为%s' % (end_time - start_time)) return inner @timmer # login = timmer(login) def login(): # 第一函数 time.sleep(0.3) # 停顿时间0.3 print('游戏开始') login() # 执行函数 inner()语法糖版
刚刚我们讨论的装饰器都是装饰不带参数的函数,现在要装饰一个带参数的函数怎么办呢?
def func(x,y): # func (x,y)实质上是 x = 5,y = 9 print(x,y) # 打印 x = 5, y = 9 func(y = 9, x = 5)补充知识点:形参=实参
import time # 导入时间模块 def timmer(f): def inner(x,y): start_time = time.time() # 记录开始时间 f(x,y) # 开始函数 login(a,b) end_time = time.time() # 记录终止时间 print('此函数所用时间为%s' % (end_time - start_time)) return inner @timmer # login = timmer(login) def login(a,b): # 第一函数 print(a,b) # 打印参数 time.sleep(0.3) # 停顿时间0.3 print('游戏开始') login(8,9) # 执行函数 inner(x,y)装饰带参数的函数【但是有局限性,无法满足参数的灵活性】
import time # 导入时间模块 def timmer(f): def inner(*args,**kwargs): start_time = time.time() # 记录开始时间 f(*args,**kwargs) # 开始函数 login(a,b) end_time = time.time() # 记录终止时间 print('此函数所用时间为%s' % (end_time - start_time)) return inner @timmer # login = timmer(login) def login(*args,**kwargs): # 第一函数 print(args,kwargs) # 打印参数 time.sleep(0) # 停顿时间0.3 print('游戏开始') @timmer def dier(*args,**kwargs): # 第二函数 print(args, kwargs) time.sleep(0.4) print('准备好了么') login(99,88,77,66,55) # 执行函数 inner(x,y) dier(999,520,0,126) # 为什么,我输给login 的数值能准确无误的送到 login 呢 这涉及到 * 的打散和重聚更换为 动态参数
我想让函数带返回值
import time # 导入时间模块 def timmer(f): def inner(*args,**kwargs): start_time = time.time() # 记录开始时间 ret = f(*args,**kwargs) # 开始函数 login(a,b) 将返回值666赋值给 ret end_time = time.time() # 记录终止时间 print('此函数所用时间为%s' % (end_time - start_time)) return ret # 将返回值666 返回给 inner(*args,**kwargs) return inner @timmer # login = timmer(login) def login(*args,**kwargs): # 第一函数 print(args,kwargs) # 打印参数 time.sleep(0) # 停顿时间0.3 print('游戏开始') return 666 # 返回值666 ,返回给 f(*args,**kwargs) @timmer def dier(*args,**kwargs): # 第二函数 print(args, kwargs) time.sleep(0.4) print('准备好了么') print(login(99,88,77,66,55)) # 执行函数 inner(x,y) 打印 login(99,88,77,66,55) 得到返回值 dier(999,520,0,126)万能装饰器 模板
相关推荐
Greatemperor 2020-07-19
勇往直前 2020-05-17
igogo00 2020-05-15
CloudXli 2020-02-21
GoatSucker 2020-02-09
千锋 2020-01-29
assastor 2020-01-29
89510194 2020-01-18
llwang0 2019-12-28
azhou 2019-12-27
Airuio 2019-12-20
sunnyJam 2019-12-08
wyqwilliam 2019-11-12
Laozizuiku 2019-11-12
zhangpan 2019-11-10
sprintwind 2011-03-23
xianhe0 2010-08-25