Python 多个装饰器的执行顺序图解

文章详细阐述了Python中装饰器的工作原理,特别是当一个函数被多个装饰器修饰时的执行顺序。首先,从最内层的装饰器开始,自内向外执行,在函数定义阶段完成装饰器的设置。然后,在函数调用时,从外层装饰器开始,按照装饰器的嵌套顺序执行,最终达到功能的组合,如日志记录和执行效率测试。
摘要由CSDN通过智能技术生成

有时候,我们需要多个装饰器修饰一个函数。比如:需要增加日志功能、增加执行效率测试功能。

装饰器函数的执行顺序是分为(被装饰函数)定义阶段和(被装饰函数)执行阶段的,装饰器函数在被装饰函数定义好后立即执行

举例:

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()

运行结果:

 分析:

  1. 在函数定义阶段:执行顺序是从最靠近函数的装饰器开始,自内而外的执行

  2. 在函数执行阶段:执行顺序由外而内,一层层执行

从靠近函数的装饰器开始执行:

先进到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")。

图片比较直观:

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,如果一个函数使用了多个装饰器,那么它们的执行顺序是从下往上的。也就是说,最下面的装饰器最先执行,最上面的装饰器最后执行,函数执行完后,装饰器执行顺序则与装饰器定义的顺序相反。 例如,下面是一个使用三个装饰器的示例: ``` python def decorator1(func): def wrapper(*args, **kwargs): print("Decorator 1 before function execution") func(*args, **kwargs) print("Decorator 1 after function execution") return wrapper def decorator2(func): def wrapper(*args, **kwargs): print("Decorator 2 before function execution") func(*args, **kwargs) print("Decorator 2 after function execution") return wrapper def decorator3(func): def wrapper(*args, **kwargs): print("Decorator 3 before function execution") func(*args, **kwargs) print("Decorator 3 after function execution") return wrapper @decorator1 @decorator2 @decorator3 def my_function(): print("Function execution") my_function() ``` 输出结果为: ``` Decorator 3 before function execution Decorator 2 before function execution Decorator 1 before function execution Function execution Decorator 1 after function execution Decorator 2 after function execution Decorator 3 after function execution ``` 可以看到,装饰器3最先执行,然后是装饰器2,最后是装饰器1。而函数执行完后,装饰器执行顺序则与装饰器定义的顺序相反,即装饰器1最先执行,然后是装饰器2,最后是装饰器3。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值