装饰器的进阶_2

案例1

 1 import time
 2 def timer(func):
 3     def inner(*args,**kwargs):
 4         start=time.time()
 5         ret=func(*args,**kwargs)
 6         end=time.time()
 7         print(end-start)
 8         return ret
 9     return inner
10 
11 @timer
12 def func1():
13     time.sleep(0.1)
14     print('123')
15     
16 @timer
17 def func2():
18     time.sleep(0.1)
19     print('1234')
20 
21 func1()
22 func2()

需求,对于func1,func2,加入不需要使用装饰器,那么直接注释,需要注释2次;如果是500个那么就需要注释500次,这样非常麻烦。有什么办法,在装饰器外面再套上一层函数

 1 import time
 2 FLAG=False#也就是说当有500多个函数需要装饰器的时候,那么只需要控制这里的true和false据可以完成对全局的控制
 3 #解决方案就是在装饰器前面再套上一层函数,对于装饰器的嵌套最多只能嵌套三层
 4 def timer_out(flag):
 5     def timer(func):
 6         def inner(*args,**kwargs):
 7             if flag:#这句代码就相当于if flag=true,只不过true可以省略
 8                 start=time.time()
 9                 ret=func(*args,**kwargs)
10                 end=time.time()
11                 print(end-start)
12                 return ret
13             else:#注意else和if条件后面唯一不同的就是缺少start和end语句,除此之外其他语句均相同
14                 ret = func(*args, **kwargs)
15                 return ret
16         return inner
17     return timer#注意这里是timer,而不是timerout
18 
19 # # timer=timer_out(FLAG)
20 # @timer 等价于func1=timer(func1)
21 @timer_out(FLAG)#注意这里是和以前装饰器最大的不同,括号内有参数.其次,可以这样理解,首先timer_out()表示执行timer_out函数,然后@这个执行的结果;相当于func1=timer(func1)
22 # 等价于下面两行代码
23 # timer=timer_out(FLAG)
24 # @timer 等价于func1=timer(func1)
25 def func1():
26     time.sleep(0.1)
27     print('123')
28 
29 @timer_out(FLAG)
30 def func2():
31     time.sleep(0.1)
32     print('1234')
33 
34 func1()
35 func2()

代码的解释:

 双层装饰器

 1 #多个装饰器装饰一个函数
 2 def wrapper1(func):#这里将f传进来
 3     def inner1():
 4         print('wrapper1,before func')
 5         func()
 6         print('wrapper1,after func')
 7     return inner1
 8 
 9 def wrapper2(func):#注意此时这个func指代的是inner1
10     def inner2():
11         print('wrapper2,before func')
12         func()
13         print('wrapper2,after func')
14     return inner2
15 
16 @wrapper1 #紧接着f=wrapper1(f)=wrapper1(inner1)
17 @wrapper2 #f=wrapper2(f)=inner2,注意装饰器是先找离他最近的函数进行执行,因此首先执行的是wrapper2
18 def f():
19     print('in f')
20 
21 f()#本质上调用的是inner2

 

上述代码可以用于场景:

1、记录用户的登录情况

2、记录记录用户的登录时间

 

posted @ 2019-01-21 22:35  舒畅123  阅读(90)  评论(0编辑  收藏  举报