装饰器
1、开放封闭原则
开放:对于添加新功能是开放的
封闭:对于修改原功能是封闭的
2、装饰器的作用
在不更改原函数调用方式的前提下对原函数添加新功能
3、装饰器
1 # ①引子——为什么要有装饰器 2 为了在不修改原函数的基础上为函数添加新功能,产生了装饰器 3 4 # ②简单装饰器 5 def deco(f): 6 def wrapper(): 7 """原函数前添加的功能""" 8 f() 9 """原函数后添加的功能""" 10 return wrapper 11 12 def func(): 13 print('这是原函数!') 14 15 func = deco(func) 16 func() 17 18 # ③装饰器的语法糖 19 def deco(f): 20 def wrapper(): 21 """原函数前添加的功能""" 22 f() 23 """原函数后添加的功能""" 24 return wrapper 25 26 @deco # ——>此处效果等同于 func = deco(func) 27 def func(): 28 print('这是原函数') 29 30 func() 31 32 # ④带返回值的装饰器 33 def deco(f): 34 def wrapper(): 35 """原函数前添加的功能""" 36 res = f() 37 """原函数后添加的功能""" 38 return res 39 return wrapper 40 41 @deco 42 def func(): 43 print('这是原函数') 44 45 func() 46 47 # ⑤带参数、带返回值的装饰器 48 def deco(f): 49 def wrapper(*args,**kwargs): 50 """原函数前添加的功能""" 51 res = f(*args,**kwargs) 52 """原函数后添加的功能""" 53 return res 54 return wrapper 55 56 @deco 57 def func(*args,**kwargs): 58 print('这是原函数') 59 60 func(*args,**kwargs) 61 62 # ⑥多层装饰器 63 # todo 64 65 # ⑦多个装饰器修饰同一个函数 66 # todo
4、装饰器的固定格式
1 def deco(f): 2 def wrapper(*args,**kwargs): 3 """原函数前添加的功能""" 4 res = f(*args,**kwargs) 5 """原函数后添加的功能""" 6 return res 7 return wrapper 8 9 @deco 10 def func(*args,**kwargs): 11 pring('这是原函数') 12 13 func(*args,**kwargs)
5、装饰器的固定格式—wraps版
如果想使用原函数的双下方法,则需要再调用系统装饰器@ wraps(func)
1 from functools import wraps 2 3 def deco(func): 4 @wraps(func) #加在最内层函数正上方 5 def wrapper(*args,**kwargs): 6 return func(*args,**kwargs) 7 return wrapper 8 9 @deco 10 def origin_func(): 11 ''' 12 这是原函数的注释 13 :return: 14 ''' 15 print('这是原函数') 16 17 # 虽然已经执行了装饰器,origin_func已经指向wrapper,但是如果用了@wraps(func)装饰器之后调用origin_func的双下方法依然是原函数origin_func的 18 print(origin_func.__name__) 19 >>> origin_func 20 21 print(origin_func.__doc__) 22 >>> 这是原函数的注释 23 >>> :return:
6、带参数的装饰器
1 def outer(flag): 2 def timer(func): 3 def inner(*args,**kwargs): 4 if flag: 5 print('''执行函数之前要做的''') 6 re = func(*args,**kwargs) 7 if flag: 8 print('''执行函数之后要做的''') 9 return re 10 return inner 11 return timer 12 13 # 此处先执行函数调用outer(False) —> 返回timer —>@timer —>func = timer(func) —> func = inner 14 @outer(False) 15 def func(): 16 print(111) 17 18 func()
7、多个装饰器装饰同一个函数
1 def wrapper1(func): 2 def inner1(): 3 print('wrapper1 ,before func') 4 func() 5 print('wrapper1 ,after func') 6 return inner1 7 8 def wrapper2(func): 9 def inner2(): 10 print('wrapper2 ,before func') 11 func() 12 print('wrapper2 ,after func') 13 return inner2 14 15 @wrapper2 # 将inner1进行装饰,即inner1 = wrapper2(inner1) = inner2 16 @wrapper1 # 先执行这个装饰器,即f = wrapper1(f) = inner1 17 def f(): 18 print('in f') 19 20 f() 21 22 # 结果 23 >>> wrapper2 ,before func 24 >>> wrapper1 ,before func 25 >>> in f 26 >>> wrapper1 ,after func 27 >>> wrapper2 ,after func
来源:https://www.cnblogs.com/kylindemi/p/12635960.html