python ------- decorator

A simple decorator

1. Why do you want to use a decorator?

  Decorator function: extend the functionality of the original function without modifying the original function and call mode

  Essence decorators: a closure function is

So let's look at a simple decoration: implements function calculates the execution time of each function

  1 import time
  2 def  wrapper(func):
  3         def inner():
  4               start=time.time()
  5               func()
  6               end=time.time()
  7               print(end-start)
  8         return inner
  9 
 10 def  hahaha():
 11         time.sleep(1)
 12         print('aaaaa')
 13 hahaha=wrapper(hahaha)
14 hahaha ()
 15  
16 simple decorator
Simple decorator View Code

The above features little introduction, imperfect, following the introduction of syntax sugar.

  1 import time
  2 def wrapper(func):
  3         def inner():
  4                start=time.time()
  5                func()
  6                end=time.time()
  7                print(end-start)
  8         return inner
  9 @wrapper
 10 def  kkk():#相当于kkk=wrapper(kkk)
 11     print('aaaaa')
 12 kkk()
 13 
 14 装饰器-------语法糖
装饰器-------语法糖 View Code

以上的装饰器都是不带参数的函数,现在装饰一个带参数的该怎么办呢?

  1 import time
  2 def timer(func):
  3     def inner(*args,**kwargs):
  4         start = time.time()
  5         re = func(*args,**kwargs)
  6         end=time.time()
  7         print(end- start)
  8         return re
  9     return inner
 10 
 11 @timer   #==> func1 = timer(func1)
 12 def func1(a,b):
 13     print('in func1')
 14     print(a,b)
 15 
 16 @timer   #==> func1 = timer(func1)
 17 def func2(a):
 18     print('in func2 and get a:%s'%(a))
 19     return 'fun2 over'
 20 
 21 func1(1,2)
 22 print(func2('aaaaaa'))
 23 
 24 原函数带多个参数的装饰器
原函数带多个参数的装饰器 View Code
  1 import time
  2 def timer(func):
  3     def inner(*args,**kwargs):
  4         start = time.time()
  5         re = func(*args,**kwargs)
  6         end=time.time()
  7         print(end - start)
  8         return re
  9     return inner
 10 
 11 @timer   #==> func1 = timer(func1)
 12 def jjj(a):
 13     print('in jjj and get a:%s'%(a))
 14     return 'fun2 over'
 15 
 16 jjj('aaaaaa')
 17 print(jjj('aaaaaa'))
 18 
带返回值的装饰器 View Code

 

二、开放封闭原则

1.对扩展是开放的

2.对修改是封闭的

三、装饰器的固定结构

  1 import time
  2 def wrapper(func):  # 装饰器
  3     def inner(*args, **kwargs):
  4         '''函数执行之前的内容扩展'''
  5         ret = func(*args, **kwargs)
  6          '''函数执行之前的内容扩展'''
  7         return ret
  8     return inner
  9 
 10 @wrapper  # =====>aaa=timmer(aaa)
 11 def aaa():
 12     time.sleep(1)
 13     print('fdfgdg')
 14 aaa()
View Code

四、带参数的装饰器

带参数的装饰器:就是给装饰器传参

   用处:就是当加了很多装饰器的时候,现在忽然又不想加装饰器了,想把装饰器给去掉了,但是那么多的代码,一个一个的去闲的麻烦,那么,我们可以利用带参数的装饰器去装饰它,这就他就像一个开关一样,要的时候就调用了,不用的时候就去掉了。给装饰器里面传个参数,那么那个语法糖也要带个括号。在语法糖的括号内传参。在这里,我们可以用三层嵌套,弄一个标识为去标识。如下面的代码示例

  1 # 带参数的装饰器:(相当于开关)为了给装饰器传参
  2 # F=True#为True时就把装饰器给加上了
  3 F=False#为False时就把装饰器给去掉了
  4 def outer(flag):
  5     def wrapper(func):
  6         def inner(*args,**kwargs):
  7             if flag:
  8                 print('before')
  9                 ret=func(*args,**kwargs)
 10                 print('after')
 11             else:
 12                 ret = func(*args, **kwargs)
 13             return ret
 14         return inner
 15     return wrapper
 16 
 17 @outer(F)#@wrapper
 18 def hahaha():
 19     print('hahaha')
 20 
 21 @outer(F)
 22 def shuangwaiwai():
 23     print('shuangwaiwai')
 24 
 25 hahaha()
 26 shuangwaiwai()
 27 
给装饰器加参数 View Code

五、多个装饰器装饰一个函数

  1 def qqqxing(fun):
  2     def inner(*args,**kwargs):
  3         print('in qqxing: before')
  4         ret = fun(*args,**kwargs)
  5         print('in qqxing: after')
  6         return ret
  7     return inner
  8 
  9 def pipixia(fun):
 10     def inner(*args,**kwargs):
 11         print('in qqxing: before')
 12         ret = fun(*args,**kwargs)
 13         print('in qqxing: after')
 14         return ret
 15     return inner
 16 @qqqxing
 17 @pipixia
 18 def dapangxie():
 19     print('饿了吗')
 20 dapangxie()
 21 
 22 '''
 23 @qqqxing和@pipixia的执行顺序:先执行qqqxing里面的 print('in qqxing: before'),然后跳到了pipixia里面的
 24         print('in qqxing: before')
 25         ret = fun(*args,**kwargs)
 26         print('in qqxing: after'),完了又回到了qqqxing里面的 print('in qqxing: after')。所以就如下面的运行结果截图一样
 27 '''
 28 
多个装饰器装饰一个函数 View Code

上例代码的运行结果截图

六、统计多少个函数被装饰了的小应用

  1 统计多少个函数被我装饰了
  2 l=[]
  3 def wrapper(fun):
  4     l.append(fun)#统计当前程序中有多少个函数被装饰了
  5     def inner(*args,**kwargs):
  6         # l.append(fun)#统计本次程序执行有多少个带装饰器的函数被调用了
  7         ret = fun(*args,**kwargs)
  8         return ret
  9     return inner
 10 
 11 @wrapper
 12 def f1():
 13     print('in f1')
 14 
 15 @wrapper
 16 def f2():
 17     print('in f2')
 18 
 19 @wrapper
 20 def f3():
 21     print('in f3')
 22 print(l)
 23 
 24 
统计多少个函数被装饰了 View Code

 

 

归类: Python相关

Guess you like

Origin www.cnblogs.com/lz1996/p/11571573.html