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做了个优化,提出了个语法糖的概念

  1. 需要将装饰器函数放到代码文件的头部
  2. 使用@timmer代替 add_method=timmer(add_method)
  3. 在需要装饰的函数的上面一行加入@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

 

。。。

posted @ 2020-09-11 20:45  yehaita  阅读(123)  评论(0编辑  收藏  举报