#装饰器
"""
1. 什么是装饰器
器指的是工具,可以定义成函数
装饰指的是为其他事物添加额外的东西来点缀
合到一起的解释:
装饰器指的是定义一个函数,该函数是用来装饰其他函数的,为其他函数添加额外的功能的
2.为何要用装饰器
开放封闭原则
开放:指的是拓展功能是开放
封闭:指的是对源代码是封闭的,
不要动源代码,还要为其添加新功能。
3. 如何用
"""
#需求:在不修改index 函数的源代码以及调用方式的前提下为其添加统计运行时间的功能
def index(x,y):
print("index %s %s" %(x,y))
index(111,222)
"""传统添加,修改了源代码,没有修改被装饰对象的调用方式"""
import time
def index(x,y):
start =time.time()
print("index %s %s" %(x,y))
stop=time.time()
print(stop-start)
index(111,222)
"""解决方案二
没有修改被装饰对象的调用方式,也没有修改了其源代码,并且加上了新功能,但是代码冗余"""
import time def index(x,y): print("index %s %s" %(x,y)) start=time.time() index(111,222) stop=time.time() print(stop-start) start=time.time() index(111,222) stop=time.time() print(stop-start) start=time.time() index(111,222) stop=time.time() print(stop-start)
"""解决方案三
问题:解决了方案二的冗余问题,但是带来了一个新问题即函数的调用方式
"""
# import time
# # def index(x,y):
# # print("index %s %s" %(x,y))
# # def wrapper():
# # start = time.time()
# # index(111, 222)
# # stop = time.time()
# # print(stop - start)
# # wrapper()
# # wrapper()
# # #
"""大方向:如何在方案三的基础上不改变函数的调用方式
功能写活了"""
import time def index(x,y): print("index %s %s" %(x,y)) def wrapper(a,b): start = time.time() index(a,b) stop = time.time() print(stop - start) wrapper(111,222) wrapper(222,333)
#方案优化一:将index 的参数写活了
import time def index(x,y,z): print("index %s %s %s" %(x,y,z)) def wrapper(*args,**kwargs): start = time.time() index(*args,**kwargs) stop = time.time() print(stop - start) wrapper(111,222,333) wrapper(222,333,555)
#优化方案二:
import time def index(x,y,z): print("index %s %s %s" %(x,y,z)) def outter(func): # func=index #func=index的内存地址 def wrapper(*args,**kwargs): start = time.time() func(*args,**kwargs) #index 的内存地址 stop = time.time() print(stop - start) return wrapper index=outter(index) """outter 现在就是装饰器,闭包函数""" #f=outer(index的内存地址) -->把outer(index内存地址)传给index #f=当初的那个wrapper函数的内存地址 index(1,2,3)
优化三:
方案三
import time def index(x,y,z): print("index %s %s %s" %(x,y,z)) def home(name): print("welcome %s to the home page" %name) def outter(func): # func=index #func=index的内存地址 def wrapper(*args,**kwargs): start = time.time() func(*args,**kwargs) #index 的内存地址 stop = time.time() print(stop - start) return wrapper index=outter(index) home=outter(home) home("claire") index(1,2,3)
在方案三的基础上再优化
import time def index(x,y,z): print("index %s %s %s" %(x,y,z)) def home(name): print("welcome %s to the home page" %name) return 3 def outter(func): # func=index #func=index的内存地址 def wrapper(*args,**kwargs): start = time.time() func(*args,**kwargs) #index 的内存地址 stop = time.time() print(stop - start) return wrapper index=outter(index) home=outter(home) #-->res=wrapper("claire") home("claire") index(1,2,3) res=home("clare") print("返回值-->",res)
welcome clare to the home page 3.0994415283203125e-06 返回值--> None
再再优化:
import time def index(x,y,z): print("index %s %s %s" %(x,y,z)) def home(name): print("welcome %s to the home page" %name) return 3 def outter(func): # func=index #func=index的内存地址 def wrapper(*args,**kwargs): start = time.time() func(*args,**kwargs) #index 的内存地址 stop = time.time() print(stop - start) return wrapper index=outter(index) home=outter(home) #-->res=wrapper("claire") home("claire") index(1,2,3) res=home("clare") print("返回值-->",res)
welcome clare to the home page 3.0994415283203125e-06 返回值--> 3
语法糖:
#在被装饰对象正上方的单独一行写@装饰器名字
import time def timmer(func): # func=index #func=index的内存地址 def wrapper(*args,**kwargs): start = time.time() res=func(*args,**kwargs) #index 的内存地址 stop = time.time() print(stop - start) return res return wrapper @timmer #index=outter(index) def index(x,y,z): print("index %s %s %s" %(x,y,z)) @timmer #home=outer(home) def home(name): print("welcome %s to the home page" %name) return 3 index(1,2,3) home("clare")
3.3855438232421875e-05
welcome clare to the home page
4.0531158447265625e-06