1、装饰器函数的本质:一个闭包函数
2、装饰器函数的作用:
在不修改原函数及其调用方式的情况下对原函数功能进行扩展
3、语法糖
格式:@装饰器名称
4、创建带返回值的装饰器
5、创建传递参数的装饰器
6、装饰器的固定格式
练习:创建一个计算函数执行花费时间的闭包函数。
首先用简单的函数来实现一下
思路:使用time函数时间戳计算该函数执行前后的时间差即为话费时间
import time
def func():
start=time.time()
for i in range(10000000):
pass
end=time.time()
print(end-start)
func()
运行结果:
0.23001337051391602
使用闭包函数实现
def func():
for i in range(1000000):
pass
def outter(fun):
def inner():
import time
start=time.time()
fun()
end=time.time()
print(end-start)
return inner
inner=outter(func)
inner()
运行结果:
0.22301292419433594
运行过程;
使用语法糖
def outter(fun):
def inner():
import time
start=time.time()
fun()
end=time.time()
print(end-start)
return inner
@outter #返回函数内存地址 等价于 func=outter(func)
def func():
for i in range(10000000):
pass
func()
运行结果:
0.22101283073425293
运行过程;
带返回值的装饰器
def timer(fun):
def inner():
import time
start=time.time()
ret=fun()
end=time.time()
print(end-start)
return ret
return inner
@timer #func=timer(func)
def func():
for i in range(10000000):
pass
return 'ok'
ret=func()
print(ret)
运行结果:
0.2580146789550781
ok
运行过程:
带参数
def timer(fun):
def inner(s):
start=time.time()
ret=fun(s) # func()
end=time.time()
print(end-start)
return ret
return inner
@timer
def func(s):
for i in range(10000000):
pass
return s
ret=func('hello') # func--->inner()
print(ret)
运行结果:
0.23401355743408203
hello
返回任意参数
def timer(fun):
def inner(*args,**kwargs):
start=time.time()
ret=fun(*args,**kwargs) # func()
end=time.time()
print(end-start)
return ret
return inner
@timer # func=timer(func)
def func(*args,**kwargs):
for i in range(10000000):
pass
return args,kwargs
ret=func('hello',name='zs') # func--->inner()
print(ret)
print(func.__doc__)
运行结果;
0.22701287269592285
(('hello',), {'name': 'zs'})
多个装饰器
def wrapper1(func): #func=inner2
print('xxxxxx')
def inner1():
print('wrapper1...start')
func() # 等价于inner2()
print('wrapper1...end')
return inner1
def wrapper2(func): #func=fun
print('zzzzz')
def inner2():
print('wrapper2...start')
func() #
print('wrapper2...end')
return inner2
# 多个妆饰器执行顺序是从下往上(从内往外)
@wrapper1 # inner1=wrapper1(inner2)
@wrapper2 # inner2=wrapper2(fun)
def fun():
print('fun.....')
fun()
运行结果:
zzzzz
xxxxxx
wrapper1...start
wrapper2...start
fun.....
wrapper2...end
wrapper1...end