装饰器的进阶_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、记录记录用户的登录时间