装饰器及进阶
1、装饰器
装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
2、装饰不带参数的函数
1 import time 2 def timer(f): #1 3 def inner(): #4 4 start=time.time() #8 5 f() #9 6 end=time.time() #12 7 print(end-start) #13 8 9 return inner #5 10 11 @timer #func=time(func) #3 #6,func的地址变成了inner的内存地址 12 def func(): #2 13 time.sleep(1) #10 14 print("你好,菜菜") #11 15 16 func() #7,这里其实是调用inner()
3、装饰带参数的函数
1 import time 2 def timer(f): #1 3 def inner(*args,**kwargs): #4 4 start=time.time() #8 5 f(*args,**kwargs) #9 6 end=time.time() #12 7 print(end-start) #13 8 return inner #5 9 10 @timer #f=timer(f) #3 #6,把inner的内存地址赋值给f 11 def f(a,b): #2 12 time.sleep(2) #10 13 print("***",a,b) #11 14 f(1,2) #7,调用f()实际是调用inner()
4、打印函数名称及带返回值的装饰器
1 import time 2 from functools import wraps 3 def timer(f): 4 @wraps(f) #给innner加带参数的装饰器,用来答应被装饰函数的函数名 5 def inner(*args,**kwargs): 6 start=time.time() 7 ret=f(*args,**kwargs) 8 end=time.time() 9 print(end-start) 10 return ret 11 return inner 12 13 @timer #f=timer(f) 14 def f(a,b): 15 time.sleep(2) 16 print("***",a,b) 17 return '新年好' 18 19 ret2=f(1,2) 20 print(ret2) #将f()函数的返回值给打印出来~ 21 print(f.__name__) #如果不加@wraps(f),打印出来是inner的函数名
5、装饰器统一格式
(1)无参数
1 def wapper(func): 2 def inner(): 3 '''在被装饰函数之前要做的事''' 4 func() 5 '''在被装饰函数之后要做的事''' 6 return inner 7 @wapper 8 def f(): 9 '''要执行的部分''' 10 f()
(2)带参数
1 def wapper(func): 2 def inner(*args,**kwargs): 3 4 '''在被装饰函数之前要做的事''' 5 func(*args,**kwargs) 6 '''在被装饰函数之后要做的事''' 7 return inner 8 9 @wapper 10 def f(a,b): 11 pass 12 13 f(1,2)
6、开放封闭原则
(1)对扩展是开放的
为什么要对扩展开放呢?
我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
(2)对修改是封闭的
为什么要对修改封闭呢?
就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
装饰器完美的遵循了这个开放封闭原则。
7、带参数的装饰器(三层装饰器),设置Flage来控制函数的执行
假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?
一个一个的取消掉? 没日没夜忙活3天。。。
过两天你领导想通了,再让你加上。。。
import time Flage=True def timmer_out(flag): def timer(f): def innner(): if flag: start=time.time() f() end=time.time() print(end-start) else: ret=f() return ret return innner
return timer @timmer_out(Flage) def func(): time.sleep(1) print("你好啊,菜菜") func()
8、多个装饰器修饰一个函数
1 def wrapper1(func): 2 def inner1(): 3 print('wrapper1 ,before func') 4 func() 5 print('wrapper1 ,after func') 6 7 return inner1 8 9 def wrapper2(func): 10 def inner2(): 11 print('wrapper2 ,before func') 12 func() 13 print('wrapper2 ,after func') 14 15 return inner2 16 17 @wrapper2 18 @wrapper1 19 def f(): 20 print('in f') 21 22 f() 23 24 #结果: 25 wrapper2 ,before func 26 wrapper1 ,before func 27 in f 28 wrapper1 ,after func 29 wrapper2 ,after func优质内容筛选与推荐>>