Python装饰器
参考:https://www.zhihu.com/question/26930016/answer/1047233982
一、装饰器是什么?
装饰器,顾名思义,就是在 不改变原函数或类的内部代码和调用方式的情况下,增强函数或类的功能的一个函数。装饰器的本质就是闭包。
1. 定义装饰器
def decorator(func): def wrapper(*args, **kwargs): '''添加额外的功能:执行被装饰函数之前的操作''' ret = func(*args, **kwargs) '''添加额外的功能:执行被装饰函数之后的操作''' return retreturn wrapper
2. 实例
1 import time 2 # version_1 3 def add_method(a,b): 4 time.sleep(2) 5 ret=a+b 6 return ret 7 def timmer(func): # decorator function 8 def inner(m,n): 9 time_start=time.time() 10 kkk=func(m,n) 11 time_end=time.time() 12 print(str(kkk)+'---'+str(time_end-time_start)) 13 return inner 14 if __name__=='__main__': 15 add_method=timmer(add_method) # decorator grammar 16 print(timmer(add_method),add_method) 17 add_method(10,11)
二、使用装饰器
1. python做了个优化,提出了个语法糖的概念
- 需要将装饰器函数放到代码文件的头部
- 使用@timmer代替 add_method=timmer(add_method)
- 在需要装饰的函数的上面一行加入@timmer
1 def timmer(func): 2 def inner(m,n): 3 time_start=time.time() 4 func(m,n) 5 time_end=time.time() 6 print(str(kkk)+'---'+str(time_end-time_start)) 7
8 return inner 9 10 def add_method(a,b): 11 time.sleep(2) 12 ret=a+b 13 return ret 14 @timmer 15 def minus_md(a,b): 16 time.sleep(1.5) 17 ret=a-b 18 return ret 19 20 if __name__=='__main__': 21 adme=add_method(10,12) 22 print(adme) 23 msmd=minus_md(25,12) 24 print(msmd)
结果:虽然被调用的函数minus_md(a,b)要求返回一个结果,但是应用装饰器之后返回值时None。
22
13---1.5006976127624512
None
2. 修改程序,使函数可以返回要求的结果。
加入装饰器不应该改变原函数的返回值,所以13应该返回给代码里面的msmd变量。但是msmd变量实际接收的是inner函数的返回值,而13返回给的是装饰器里面的函数func(m,n),也就是kkk变量,所以现在我们要解决的问题就是将kkk给inner的返回值。
1 def timmer(func): 2 def inner(m,n): 3 time_start=time.time() 4 kkk=func(m,n) # 获得调用函数的返回值 5 time_end=time.time() 6 print(str(kkk)+'---'+str(time_end-time_start)) 7 return kkk # 将结果返回给程序结果 8 return inner 9 10 def add_method(a,b): 11 time.sleep(2) 12 ret=a+b 13 return ret 14 @timmer 15 def minus_md(a,b): 16 time.sleep(1.5) 17 ret=a-b 18 return ret 19 20 if __name__=='__main__': 21 adme=add_method(10,12) 22 print(adme) 23 msmd=minus_md(25,12) 24 print(msmd)
结果:
22 13---1.5002110004425049 13
3. 装饰器传递参数
使用万能参数传递参数:
在装饰器内部函数定义中,使用 ‘ * ’ 将参数聚合成元组;在装饰器内部函数的执行时,将在函数定义时 ‘ * ’ 聚合的参数打散。
1 def timmer(func): 2 def inner(*args,**kwargs): 3 time_start=time.time() 4 kkk=func(*args,**kwargs) 5 time_end=time.time() 6 print(str(kkk)+'---'+str(time_end-time_start)) 7 return kkk 8 return inner
。。。