10 Day Python之装饰器

删除回忆录丶 提交于 2020-04-05 18:14:32

装饰器

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
View Code

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)
View Code

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:
View Code

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()
View Code

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
View Code

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!