1 面试的时候,经常被问过装饰器,所以掌握好装饰器非常重要。
2 一.装饰器形成的过程:1.最简单的装饰器。2.被装饰的函数有返回值。3.被装饰的函数有一个参数。4.被装饰的函数有多个位置参数。5.被装饰的函数有多个位置参数和关键字参数。
3 二.装饰器的作用:不修改被装饰的函数的代码和调用方式,增加新的功能。
4 三.原则:开放封闭原则。
5 四.语法糖:@wrapper
6 五.装饰器的固定模式。
7
8
9 一.装饰器形成的过程:1.最简单的装饰器。注意:下面代码没修改被装饰的函数的代码,但是调用使用了timmer(test)而不是test(),改变了调用方式,会导致
10 以前调用该函数的程序发生错误(如果以前有人使用过你写的函数)。
11 使用 时间函数 计算 代码 运行的时间
12 import time
13 def timmer(t): #timmer(t)是时间装饰器
14 start = time.time() #开始:函数开始运行的时间
15 time.sleep(0.01) #让函数睡眠0.01秒,否则打印的结果是0.0。
16 t() #过程:函数运算的过程。t()表示调用被装饰的函数。
17 end = time.time() #结束:函数结束运行的时间
18 print(end-start) #打印出运算的过程需要多少时间
19 def test():
20 print('今天必须非常努力,我要寻找热爱学习热爱工作的自己,我会为自己的努力而感到快乐幸福和满足')
21 timmer(test) #把需要计算运行时间的函数对象(或者说是地址)传给时间函数timmer
22
23
24 1.在不准修改test函数的情况下,装饰器发挥非常重要的作用:不修改test函数的代码,那么调用test函数的方式也不能修改,但是想在函数前后增加功能。
25 2.下面例子,test()这种调用函数的方式没有改变,但是给test函数增加了计算运行时间的功能。
26 3.开放封闭原则:对拓展(增加功能)是开放的,但是对修改被装饰的函数是封闭的。
27
28 一.装饰器形成的过程:1.最简单的装饰器:不修改被装饰的函数的代码和调用方式,使用了内部函数和闭包。
29 import time
30 def timmer(f): #装饰器函数
31 def inner():
32 start = time.time()
33 time.sleep(0.01)
34 f() #被装饰的函数
35 end = time.time()
36 print(end-start)
37 return inner #test=timmer(test)=inner,返回inner的id给timmer(test)
38 test = timmer(test)
39 def test():
40 print('今天必须非常努力,我要寻找热爱学习热爱工作的自己,我会为自己的努力而感到快乐和幸福和满足')
41 test() #test()=inner()
42
43
44
45 #一.装饰器形成的过程:2.被装饰的函数有返回值。
46 import time
47 def timmer(f): #装饰器函数
48 def inner():
49 start = time.time()
50 time.sleep(0.01)
51 n = f() #被装饰的函数
52 end = time.time()
53 print(end-start)
54 return n
55 return inner #test=timmer(test)=inner,返回inner的id给timmer(test)
56 test = timmer(test)
57 def test(): #被装饰的函数
58 print('今天必须非常努力,我要寻找热爱学习热爱工作的自己,我会为自己的努力而感到快乐和幸福和满足')
59 return 10000000
60 print(test()) #test()=inner()
61
62
63 #一.装饰器形成的过程:3.被装饰的函数有一个参数。
64 import time
65 def timmer(f): #装饰器函数
66 def inner(a):
67 start = time.time()
68 time.sleep(0.01)
69 n = f(a) #被装饰的函数
70 end = time.time()
71 print(end-start)
72 return n
73 return inner #test=timmer(test)=inner,返回inner的id给timmer(test)
74 test = timmer(test)
75 def test(a): #被装饰的函数
76 print('加油',a)
77 return 10000000
78 print(test(10000000)) #test(a)=inner(a)
79
80
81 一.装饰器形成的过程:4.被装饰的函数有多个位置参数。
82 import time
83 def timmer(f): #装饰器函数
84 def inner(*args):
85 start = time.time()
86 time.sleep(0.01)
87 n = f(*args) #被装饰的函数
88 end = time.time()
89 print(end-start)
90 return n
91 return inner #test=timmer(test)=inner,返回inner的id给timmer(test)
92 test = timmer(test)
93 def test(*args): #被装饰的函数
94 print('加油',args)
95 return 10000000
96 print(test(1,2,3)) #test(*args)=inner(*args)
97
98
99 #一.装饰器形成的过程:5.被装饰的函数有多个位置参数和关键字参数。
100 import time
101 def timmer(f): #装饰器函数
102 def inner(*args,**kwargs):
103 start = time.time()
104 time.sleep(0.01)
105 n = f(*args,**kwargs) #被装饰的函数
106 end = time.time()
107 print(end-start)
108 return n
109 return inner #test=timmer(test)=inner,返回inner的id给timmer(test)
110 test = timmer(test)
111 def test(*args,**kwargs): #被装饰的函数
112 print('加油',args,kwargs)
113 return 10000000
114 print(test(1,2,3,t=8000000,m=10000000)) #test(*args,**kwargs)=inner(*args,**kwargs)
115
116
117 四.语法糖:@wrapper
118 import time
119 def timmer(f):
120 def inner():
121 start = time.time()
122 time.sleep(0.01)
123 n = f()
124 end = time.time()
125 print(end - start)
return n
126 return inner
127 @timmer #语法糖@timmer相当于 func=timmer(func) 没有语法糖或func=timmer(func),装饰器就无法起作用。
128 def func():
129 print('今天继续加油')
130 func()
131
132
133
134 五.装饰器的固定模式。wrapper是装饰的意思。
135 def wrapper(f):
136 def inner(*args,**kwargs):
137 '''在被装饰的函数前面增加功能'''
138 ret = f(*args,**kwargs)
139 '''在被装饰的函数后面增加功能'''
140 return ret
141 return inner #上面五句话是装饰器的固定模式。
142 @wrapper
143 def func(*args,**kwargs):
144 return args,kwargs
145 print(func(1,2,3,m=10000000))
146
147 六.装饰器的执行过程:
148 1. def wrapper(f):
149 4. def inner(*args,**kwargs):
150 7. '''在被装饰的函数前面增加功能'''
151 8. ret = f(*args,**kwargs)
152 9. '''在被装饰的函数后面增加功能'''
153 10. return ret #返回func(1,2,3,m=10000000)的返回值,因为第6步使用了print,所以被装饰的函数的返回值就被打印出来。
154 5. return inner #返回inner给wrapper(func),那么inner=wrapper(func)=func
155 3. @wrapper #func=wrapper(func)传参
156 2. def func(*args,**kwargs):
157 return args,kwargs
158 6. print(func(1,2,3,m=10000000)) #func=inner,相当于print(inner(1,2,3,m=10000000)),接着内部函数inner执行。
159 调用func函数实际上是调用了装饰器的内部函数:inner函数。