有时候,我们需要多个装饰器修饰一个函数。比如:需要增加日志功能、增加执行效率测试功能。
装饰器函数的执行顺序是分为(被装饰函数)定义阶段和(被装饰函数)执行阶段的,装饰器函数在被装饰函数定义好后立即执行
举例:
from time import sleep, time
def mylog(func):
print("mylog, start")
def infunc2():
print("日志记录, start")
func()
print("日志记录, end")
print("mylog, end")
return infunc2
def cost_time(func):
print("cost_time start")
def infunc1():
print("开始计时")
start = time()
func()
end = time()
print(f"耗费时间:{end - start}")
print("cost_time end")
return infunc1
"""
从靠近函数的装饰器开始执行:先进到cost_time,print("cost_time start"),
print("cost_time end"),返回infunc1, 把这个作为参数传给mylog,
进到mylog里面, print("mylog, start"),print("mylog, end"),返回infunc2,
进到infunc2里面,print("日志记录, start"),运行func(),此时因为参数是infunc1,
所以进到infunc1里面,print("开始计时"),运行func(),它的参数是func2,
所以进到func2,print("func2, start"),print("func2, end"),
再接下去print(f"耗费时间:{end - start}"),把infunc1运行完了,
回到infunc2,print("日志记录, end")。
"""
# mylog(cost_tine(fun2))
@mylog
@cost_time
def func2():
print("func2, start")
sleep(3)
print("func2, end")
func2()
运行结果:
分析:
-
在函数定义阶段:执行顺序是从最靠近函数的装饰器开始,自内而外的执行
-
在函数执行阶段:执行顺序由外而内,一层层执行
从靠近函数的装饰器开始执行:
先进到cost_time,print("cost_time start"),print("cost_time end"),返回infunc1, 把这个作为参数传给mylog,进到mylog里面, print("mylog, start"),print("mylog, end"),返回infunc2,进到infunc2里面,print("日志记录, start"),运行func(),此时因为参数是infunc1,所以进到infunc1里面,print("开始计时"),运行func(),它的参数是func2,所以进到func2,print("func2, start"),print("func2, end"),再接下去print(f"耗费时间:{end - start}"),把infunc1运行完了,回到infunc2,print("日志记录, end")。
图片比较直观: