装饰器
1.什么是装饰器?
装饰器指的是为被装饰对象添加新功能的工具
装饰器本身可以是任意可调用对象
被装饰对象本身也可以是任意可调用对象
2.为何要用 装饰器
开放封闭原则:对修改封闭,对扩展开放
装饰器的实现原则:
1.不能修改被装饰对象的源代码
2.不能修改被装饰对象的调用方式
装饰器的目的:
就是在遵循原则1和2的前提下为被装饰对象添加新功能
3.如何使用
import time
def index():
time.sleep(1)
print('welcome to index page')
index()
#统计运行时间
思路1
import time
def index():
start=time.time()
time.sleep(1)
print('welcome to index page')
stop=time.time()
print('run time is %s'%(stop - start))
index()
修改了源代码
思路2
import time
def index():
time.sleep(1)
print('welcome to index page')
start=time.time()
index()
stop=time.time()
print('run time is %s' %(stop - start))
不能重复使用,下面我们将它写在一个函数里面
思路3
import time
def index():
time.sleep(1)
print('welcome to index page')
def wrapper():
start=time.time()
index()
stop=time.time()
print('run time is %s' %(stop - start))
wrapper()
可以重复调用但是写死了,只能修饰index,下面我们要将其写活,将index换成func
思路4:
import time
def index():
time.sleep(1)
print('welcome to index page')
def wrapper():
start=time.time()
func()
stop=time.time()
print('run time is %s' %(stop - start))
wrapper()
函数体需要外部传进来参数,两种解决方案 1.直接传参 2.闭包函数
直接传参:
import time
def index():
time.sleep(1)
print('welcome to index page')
def wrapper(func):
start=time.time()
func() #index()
stop=time.time()
print('run time is %s' %(stop - start))
wrapper(index)
本来使用index()调用的,这个直接改变了人家的调用方式违反了开放封闭原则
闭包函数:
import time
def index():
time.sleep(1)
print('welcome to index page')
def timer(func):
#func=最原始index的内存地址
def wrapper():
start=time.time()
func() #func=最原始index的内存地址
stop=time.time()
print('run time is %s' %(stop - start))
return wrapper
index=timer(index) #翻译一下:index=(timer(最原始index的内存地址)) #index=wrapper的内存地址
index() #wrappper的内存地址()
思路5:完善这个装饰器
如果有返回值:
import time
def index():
time.sleep(1)
print('welcome to index page')
return 1234
def timer(func):
def wrapper():
start=time.time()
res=func()
stop=time.time()
print('run time is %s' %(stop - start))
return res
return wrapper
index=timer(index)
res=index()
print(res)
如果还有其他函数被装饰:
import time
def index():
time.sleep(1)
print('welcome to index page')
return 1234
def home(name):
time.sleep(1)
print('welcome %s to home page' %name)
def timer(func):
def wrapper(*args,**kwargs):
start=time.time()
res=func(*args,**kwargs)
stop=time.time()
print('run time is %s' %(stop - start))
return res
return wrapper
index=timer(index)
index()
home=timer(home)
home('egon')
思路6:语法糖 在被装饰对象正上方单独一行写上@装饰器的名字
import time
def timer(func):
def wrapper(*args,**kwargs):
start=time.time()
res=func(*args,**kwargs)
stop=time.time()
print('run time is %s' %(stop - start))
return res
return wrapper
@timer 作用:#index=timer(index) #翻译一下:index=(timer(最原始index的内存地址)) #index=wrapper的内存地址
def index():
time.sleep(1)
print('welcome to index page')
return 1234
@timer
def home(name):
time.sleep(1)
print('welcome %s to home page' %name)
index()
home('egon')
装饰器模板:
def outter(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return wrapper