装饰器
1.装饰器的作用
在不改变原函数代码和调用方式的基础上,为它增加新功能
2.装饰器原理
import time
def add(a, b):
time.sleep(1)
return a + b
1.需求:统计add的运行时间
start_time = time.time()
add(3,4)
end_time = time.time()
print('运行时间是:',end_time-start_time)
2.需求:写一个通用的,以后只要统计任意函数运行时间,都使用通用的
def outer(func):
start_time = time.time()
func(3,4)
end_time = time.time()
print('运行时间是:', end_time - start_time)
outer(add)
虽然能实现需求,但是改变了调用方式,不行
--->优化
def outer(func):
def inner(a,b):
start_time = time.time()
res = func(a,b)
end_time = time.time()
print('运行时间是:', end_time - start_time)
return res
return inner
inner=outer(add)
# 调用inner就是在执行,inner内部包了add函数,inner叫闭包函数,
# 闭包函数:定义在外部,对内部作用域有引用
inner() # 还是改变了调用方式
--->继续优化
3.实现需求,下面这种就是装饰器
def outer(func):
def inner(a,b):
start_time = time.time()
res = func(a,b)
end_time = time.time()
print('运行时间是:', end_time - start_time)
return res
return inner
add = outer(add)
add(3,4) # 本质调用inner,add 本质就是inner,inner要能接收a,b,并且要有返回结果
4.以后想装饰哪个函数就可以直接使用,按照如下操作,比较麻烦
def ee():
print('ee')
ee = outer(ee)
ee()
5.语法糖,以后只要按如下方式编写代码,就能实现上诉功能
@outer # 等同于ee = outer(ee) 语法糖会把被装饰器的函数ee,当做参数,传入outer,并且把outer的执行结果,返回赋值给ee
def ee():
print('ee')
ee()
以后ee其实已经不是ee了,是inner了,执行ee本质在执行inner
3.装饰器模板
def outer(func):
def inner(*args,**kwargs):
# 被装饰器函数,执行之前做的
start_time = time.time()
res = func(*args,**kwargs)
end_time = time.time()
# 被装饰器函数,执行之后做的
print('运行时间是:',end_time-start_time)
return res
return inner
@outer
def add(a, b):
time.sleep(2)
return a + b
add(1,2)