day3-python之装饰器(四)
分类:
IT文章
•
2023-11-30 12:55:25
一、简单的装饰器
装饰器本质上就是一个python函数,可以让其他函数在不需要任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。
简单来讲,在原有的函数前后增加功能,且不改变原函数的调用方式。
装饰器的本质:就是一个闭包函数
装饰器的应用场景:插入日志、性能测试、事务处理、缓存等等场景。
实现计算每个函数的执行时间的功能:
1 import time
2 def timmer(f):
3 def inner():
4 start_time = time.time()
5 f()
6 end_time = time.time()
7 print(end_time - start_time)
8 return inner
9
10 def func():
11 print('begin func')
12 time.sleep(0.1)
13 print('end func')
14
15 func = timmer(func)
16 func() # ==> inner()
简单的装饰器
以上功能不简洁,不完美。引出语法糖。
1 import time
2 def timmer(f):
3 def inner():
4 start_time = time.time()
5 f()
6 end_time = time.time()
7 print(end_time - start_time)
8 return inner
9
10 @timmer # ==> func = timmer(func)
11 def func():
12 print('begin func')
13 time.sleep(0.1)
14 print('end func')
15
16 func() # ==> inner()
装饰器-------语法糖
以上装饰器都是不带参数函数,现在装饰一个带参数的该怎么办?
1 import time
2 def timmer(f):
3 def inner(*args,**kwargs):
4 start_time = time.time()
5 ret = f(*args,**kwargs)
6 end_time = time.time()
7 print(end_time - start_time)
8 return ret
9 return inner
10
11 @timmer # ==> func = timmer(func)
12 def func(a,b):
13 print('begin func',a)
14 time.sleep(0.1)
15 print('end func',b)
16 return True
17
18 func(1,2) # ==> inner()
原函数带多个参数的装饰器
1 import time
2
3 def timer(func):
4 def inner(a):
5 start = time.time()
6 func(a)
7 print(time.time() - start)
8 return inner
9
10 @timer
11 def func1(a):
12 print(a)
13
14 func1(1)
原函数带一个参数的装饰器
1 import time
2 def timer(func):
3 def inner(*args,**kwargs):
4 start = time.time()
5 re = func(*args,**kwargs)
6 end=time.time()
7 print(end- start)
8 return re
9 return inner
10
11 @timer #==> func1 = timer(func1)
12 def func1(a,b):
13 print('in func1')
14 print(a,b)
15
16 @timer #==> func1 = timer(func1)
17 def func2(a):
18 print('in func2 and get a:%s'%(a))
19 return 'fun2 over'
20
21 func1(1,2)
22 print(func2('aaaaaa'))
原函数带多个参数的装饰器
1 import time
2 def timer(func):
3 def inner(*args,**kwargs):
4 start = time.time()
5 re = func(*args,**kwargs)
6 end=time.time()
7 print(end - start)
8 return re
9 return inner
10
11 @timer #==> func1 = timer(func1)
12 def jjj(a):
13 print('in jjj and get a:%s'%(a))
14 return 'fun2 over'
15
16 jjj('aaaaaa')
17 print(jjj('aaaaaa'))
带返回值的装饰器
二、开放封闭原则
1.对扩展是开放的
任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
2.对修改是封闭的
因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
装饰器完美的遵循了这个开放封闭原则。
三、装饰器的固定结构
1 def timmer(f):
2 def inner(*args,**kwargs):
3 '''执行函数之前要做的'''
4 ret = f(*args,**kwargs)
5 '''执行函数之后要做的'''
6 return ret
7 return inner
装饰器的固定格式
1 # 带参数的装饰器:(相当于开关)为了给装饰器传参
2 F=True#为True时就把装饰器给加上了
3 # F=False#为False时就把装饰器给去掉了
4 def outer(flag):
5 def wrapper(func):
6 def inner(*args,**kwargs):
7 if flag:
8 print('before')
9 ret=func(*args,**kwargs)
10 print('after')
11 else:
12 ret = func(*args, **kwargs)
13 return ret
14 return inner
15 return wrapper
16
17 @outer(F)#@wrapper
18 def hahaha():
19 print('hahaha')
20
21 @outer(F)
22 def shuangwaiwai():
23 print('shuangwaiwai')
24
25 hahaha()
26 shuangwaiwai()
给装饰器加参数
1 def qqqxing(fun):
2 def inner(*args,**kwargs):
3 print('in qqxing: before')
4 ret = fun(*args,**kwargs)
5 print('in qqxing: after')
6 return ret
7 return inner
8
9 def pipixia(fun):
10 def inner(*args,**kwargs):
11 print('in qqxing: before')
12 ret = fun(*args,**kwargs)
13 print('in qqxing: after')
14 return ret
15 return inner
16 @qqqxing
17 @pipixia
18 def dapangxie():
19 print('饿了吗')
20 dapangxie()
21
22 '''
23 @qqqxing和@pipixia的执行顺序:先执行qqqxing里面的 print('in qqxing: before'),然后跳到了pipixia里面的
24 print('in qqxing: before')
25 ret = fun(*args,**kwargs)
26 print('in qqxing: after'),完了又回到了qqqxing里面的 print('in qqxing: after')。所以就如下面的运行结果截图一样
27 '''
多个装饰器装饰一个函数
1 import time
2 def outer(flag):
3 def timmer(f):
4 def inner(*args,**kwargs):
5 if flag == True:
6 start_time = time.time()
7 ret = f(*args,**kwargs)
8 end_time = time.time()
9 print(end_time - start_time)
10 else:
11 ret = f(*args,**kwargs)
12 return ret
13 return inner
14 return timmer
15
16 @outer(False)
17 def func(a,b):
18 print('begin func',a)
19 time.sleep(0.1)
20 print('end func',b)
21 return True
22
23 func(1,2)