1.wraps的使用
1 def wrapper(func): 2 def inner(*args, **kwargs): 3 print('在被装饰的函数执行之前做的事') 4 ret = func(*args, **kwargs) 5 print('在被装饰的函数执行之后做的事') 6 return ret 7 return inner 8 9 @wrapper 10 def holiday(day): 11 ''' 12 我们正在做一个测试 13 ''' 14 print('还有%s成为python大牛'%day) 15 return 'happy' 16 17 print(holiday.__name__) #输出结果:这里我们打印的是holiday,但实际输出是inner 18 print(holiday.__doc__) #输出结果:None 查看函数的注释
这与我们期望的打印holiday函数本身不相符,下面我们开始改进
1 from functools import wraps 2 def wrapper(func): 3 @wraps(func) 4 def inner(*args, **kwargs): 5 print('在被装饰的函数执行之前做的事') 6 ret = func(*args, **kwargs) 7 print('在被装饰的函数执行之后做的事') 8 return ret 9 10 return inner 11 12 13 @wrapper 14 def holiday(day): 15 ''' 16 我们正在做一个测试 17 ''' 18 print('还有%s成为python大牛' % day) 19 return 'happy' 20 21 22 print(holiday.__name__) #输出结果:holiday 23 print(holiday.__doc__) #输出结果: 我们正在所一个测试
2.带参数的装饰器
引子:假如有一个季度考核,考核对象是500个函数,这时候我们就可以使用装饰器了
1 import time 2 3 def timmer(func): 4 def innner(*args,**kwargs): 5 start = time.time() 6 ret = func(*args,**kwargs) 7 end = time.time() 8 print(end - start) 9 return ret 10 return innner 11 12 @timmer 13 def wahaha(): 14 time.sleep(0.1) 15 print(wahaha.__name__) 16 17 @timmer 18 def erguotou(): 19 time.sleep(0.1) 20 print(erguotou.__name__) 21 22 wahaha() 23 erguotou()
这样子的话,考核的目的我们确实是实现了,但是,等到不需要考核的时候
我们就麻烦了,我们需要一行行注释代码?有没有更简单的方法呢?
1 import time 2 FLAGE = True 3 def timmer_out(flag): 4 def timmer(func): 5 def innner(*args,**kwargs): 6 if flag == True: 7 start = time.time() 8 ret = func(*args,**kwargs) 9 end = time.time() 10 print(end - start) 11 return ret 12 else: 13 ret = func(*args,**kwargs) 14 return ret 15 return innner 16 return timmer 17 18 @timmer_out(FLAGE) #注意这里有一个参数FLAGE 19 def wahaha(): 20 time.sleep(0.1) 21 print(wahaha.__name__) 22 23 @timmer_out(FLAGE) #注意这里有一个参数FLAGE 24 def erguotou(): 25 time.sleep(0.1) 26 print(erguotou.__name__) 27 28 wahaha() 29 erguotou()
3.多个装饰器装饰一个函数
1 def wrapper1(func): 2 def inner(): 3 print('wrapper1, before func') 4 func() 5 print('wrapper1, after func') 6 return inner 7 8 def wrapper2(func): 9 def inner(): 10 print('wrapper2, before func') 11 func() 12 print('wrapper2, after func') 13 return inner 14 15 @wrapper2 16 @wrapper1 17 def f(): 18 print('in f') 19 f() #输出结果: wrapper2, before func 20 # wrapper1, before func 21 # in f 22 # wrapper1, after func 23 # wrapper2, after func