装饰器
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
