• 多层装饰器执行顺序


    一、叠加多个装饰器

    加载顺序:自下而上
    运行顺序:自上而下

    代码:

    def deco1(func1):   #func1=wrapper2的内存地址
        print('装饰器1')
        def wrapper1(*args,**kwargs):
            print('wrapper1===>')
            res1=func1(*args,**kwargs)
            return res1
        return wrapper1
    
    
    def deco2(func2): #func2= wrapper3的内存地址
        print('装饰器2')
        def wrapper2(*args,**kwargs):
            print('wrapper2===>')
            res2=func2(*args,**kwargs)
            return res2
        return wrapper2
    
    
    def deco3(func3):          #func3=最原始的那个被装饰函数的内存地址
        print('装饰器3')
        def wrapper3(*args,**kwargs):
            print('wrapper3===>')
            res3=func3(*args,**kwargs)
            return res3
        return wrapper3
    
    
    @deco1   #deco1(wrapper2的内存地址)=》wrapper1的内存地址
    @deco2   #deco2(wrapper3的内存地址)=》wrapper2的内存地址
    @deco3   #deco3(最原始的那个被装饰函数的内存地址)=》wrapper3的内存地址
    def index(x,y):
        print('index==>',x,y)


    index(1,2)

    运行结果

    装饰器3
    装饰器2
    装饰器1
    wrapper1===>
    wrapper2===>
    wrapper3===>
    index==> 1 2




    那么为什么会是这样的顺序???

    
    

    看到这个执行结果,我们可能会疑惑,为什么先打印了装饰器3,装饰器2,装饰器1呢?

    我们去掉函数执行,只留下函数的定义,代码如下:

    def deco1(func1):   #func1=wrapper2的内存地址
        print('装饰器1')
        def wrapper1(*args,**kwargs):
            print('wrapper1===>')
            res1=func1(*args,**kwargs)
            return res1
        return wrapper1
    
    
    def deco2(func2): #func2= wrapper3的内存地址
        print('装饰器2')
        def wrapper2(*args,**kwargs):
            print('wrapper2===>')
            res2=func2(*args,**kwargs)
            return res2
        return wrapper2
    
    
    def deco3(func3):          #func3=最原始的那个被装饰函数的内存地址
        print('装饰器3')
        def wrapper3(*args,**kwargs):
            print('wrapper3===>')
            res3=func3(*args,**kwargs)
            return res3
        return wrapper3
    
    
    @deco1   #deco1(wrapper2的内存地址)=》wrapper1的内存地址
    @deco2   #deco2(wrapper3的内存地址)=》wrapper2的内存地址
    @deco3   #deco3(最原始的那个被装饰函数的内存地址)=》wrapper3的内存地址
    def index(x,y):
        print('index==>',x,y)

    执行结果:

    装饰器3
    装饰器2
    装饰器1

    也就是说在index方法没有执行的时候,装饰器函数就执行了

    此处我们需要先弄清楚,函数和函数调用的区别,index是一个函数,它的值是函数本身,index()是函数的调用,它的值是函数的执行结果。

    在被装饰器函数定义阶段,也就是函数调用之前

    @deco1   #deco1(wrapper2的内存地址)=》wrapper1的内存地址
    @deco2   #deco2(wrapper3的内存地址)=》wrapper2的内存地址
    @deco3   #deco3(最原始的那个被装饰函数的内存地址)=》wrapper3的内存地址
    def index(x,y):
        print('index==>',x,y)

    这段代码相当于:

    deco1(deco2(deco3(index)))

    deco1和deco2和deco3的返回值都是一个函数,所以deco1(deco2(deco3(index)))也是一个函数,deco1包含了deco2,deco2包含了deco3

    index(1,3)相当于deco1(deco2(deco3(index)))()

    所以index()在执行时,deco3--》deco2--》deco1--》deco1--》deco2--》deco3--》index--》deco3--》deco2--》deco1按照这样的顺序执行

  • 相关阅读:
    git常用操作
    Spring学习(5):DI的配置
    007.python学习课程(元组)
    006.python学习课程(列表)
    004.python学习课程(循环语句)
    005.python学习课程(字符串)
    003.python学习课程(条件语句)
    002.python学习课程(输入、赋值、计算)
    001.python学习课程(环境搭建、变量、数据类型、输出)
    asterisk 目录
  • 原文地址:https://www.cnblogs.com/ltyc/p/14453913.html
Copyright © 2020-2023  润新知