器指的是工具,可以定义成成函数
装饰指的是为其他事物添加额外的东西点缀
合到一起的解释:装饰器指的定义一个函数,该函数是用来为其他函数添加额外的功能
开放封闭原则
开放:指的是对拓展功能是开放的
封闭:指的是对修改源代码是封闭的
装饰器就是在不修改被装饰器对象源代码以及调用方式的前提下为被装饰对象添加新功能
需求:在不修改index函数的源代码以及调用方式的前提下为其添加统计运行时间的功能
让我们一步步的得到装饰器
def index(x,y): time.sleep(3) print(‘index %s %s‘ %(x,y)) index(111,222)
解决方案一失败:没有修改被装饰对象的调用方式,但是修改了其源代码
import time def index(x,y): start=time.time() time.sleep(3) print(‘index %s %s‘ %(x,y)) stop = time.time() print(stop - start) index(111,222)
解决方案二失败:没有修改被装饰对象的调用方式,也没有修改了其源代码,并且加上了新功能,但是代码冗余
import time def index(x,y): time.sleep(3) print(‘index %s %s‘ %(x,y)) start=time.time() index(111,222) stop=time.time() print(stop - start)
解决方案三失败:解决了方案二代码冗余问题,但带来一个新问题即函数的调用方式改变了
import time def index(x,y): time.sleep(3) print(‘index %s %s‘ %(x,y)) def wrapper(): start=time.time() index(111,222) stop=time.time() print(stop - start) wrapper()
大方向:如何在方案三的基础上不改变函数的调用方式
方案三优化一:将index的参数写活了
import time def index(x,y): time.sleep(3) print(‘index %s %s ‘ %(x,y)) def wrapper(*args,**kwargs): start=time.time() index(*args,**kwargs) stop=time.time() print(stop - start) wrapper(3333,4444)
方案三优化二:在优化一的基础上把被装饰对象写活了,原来只能装饰index
import time def index(x,y): time.sleep(3) print(‘index %s %s %s‘ %(x,y)) def home(name): time.sleep(2) print(‘welcome %s to home page‘ %name) def outter(func): def wrapper(*args,**kwargs): start=time.time() func(*args,**kwargs) stop=time.time() print(stop - start) return wrapper index=outter(index) # index=wrapper的内存地址 home=outter(home) # home=wrapper的内存地址 home(‘egon‘)
方案三优化三:将wrapper做的跟被装饰对象一模一样,以假乱真
import time def home(name): time.sleep(2) print(‘welcome %s to home‘%name) return 123 def index(x,y): time.sleep(2) print(‘index %s %s‘ % (x, y)) def outtor(func): def wrapper(*args,**kwargs): start = time.time() res = func(*args,**kwargs) #返回值也要一样 stop = time.time() print(stop-start) return res return wrapper index = outtor(index)# 偷梁换柱:index这个名字指向的wrapper函数的内存地址 index(1,2) home = outtor(home)# 偷梁换柱:home这个名字指向的wrapper函数的内存地址 res = home(‘jjj‘) print(res)
最终结果:
语法糖:在被装饰对象正上方的单独一行写@装饰器名字(让你开心的语法
import time @outtor def home(name): time.sleep(2) print(‘welcome %s to home‘%name) return 123 @outtor def index(x,y): time.sleep(2) print(‘index %s %s‘ % (x, y)) def outtor(func): def wrapper(*args,**kwargs): start = time.time() res = func(*args,**kwargs) #返回值也要一样 stop = time.time() print(stop-start) return res return wrapper index(1,2) res = home(‘jjj‘) print(res)
原文:https://www.cnblogs.com/bk134/p/12552983.html