多层装饰器例子

def outter1(func1):
    print('加载了outter1')
    def wrapperl(*args,**kwargs):
        print('执行了wrapperl')
        res1=func1(*args,**kwargs)
        return res1
    return wrapperl
def outter2(func2):
    print('加载了outter2')
    def wrapper2(*args,**kwargs):
        print('执行了wrapper2')
        res2=func2()
        return res2
    return wrapper2
def outter3(func3):
    print('加载了outter3')
    def wrapper3(*args,**kwargs):
        print('执行了wrapper3')
        res3=func3(*args,**kwargs)
        return res3
    return wrapper3
@outter1
@outter2
@outter3
def index():
    print('from index')
index()

分析调用过程

@outter1  # index = outter1(wrapper2)
@outter2  # wrapper2 = outter2(wrapper3)
@outter3  # wrapper3 = outter3(最原始的index函数地址)
def index():
    print('from index')
# @outter3紧贴index(),所以此时outter3调用的是index(),而返回的实际上是wrapper3,所以wrapper3 = outter3(index).(这里传入的是最原始的index函数内存地址)

# @outter3的调用完之后,这时@outter2看到的是wrapper3,所以这时outter2调用的就是wrapper3,而返回的是wrapper2,所以有 wrapper2 = outter2(wrapper3)

# 同理,当@outter2调用完之后,@outter1看到的就是wrapper2,所以outter1这时调用的就是wrapper2,因为outter1的上层没有语法糖继续调用,所以这里就给它起名和被装饰函数同名,也就是index,所以有index = outter1(wrapper2)

# 根据上面的例子中,调用wrapper3、wrapper2、wrapper1之前会打印一句话,于是,根据我们推理的加载顺序,在没有调用index()时它打印的顺序就是
"""
加载了outter3
加载了outter2
加载了outter1
"""

分析完调用顺序后我们来看它的运行顺序

def outter1(func1):
    print('加载了outter1')
    def wrapper1(*args,**kwargs):  # 根据上面的推导结果,我们调用index()实际上就是调用wrapper1
        print('执行了wrapperl')  # 调用wrapper1时首先打印这句话
        res1=func1(*args,**kwargs)  # 然后执行到这一步需要调用func1,而func1实际上是在推导过程中outter1括号中的wrapper2,
        return res1
    return wrapper1
def outter2(func2):
    print('加载了outter2')
    def wrapper2(*args,**kwargs):  # 于是来执行wrapper2
        print('执行了wrapper2')  # 执行wrapper2时打印这句话
        res2=func2()  # 然后执行到这一步需要调用func2,func2与上面的func1同理,所以在这里它就是调用wrapper3
        return res2
    return wrapper2
def outter3(func3):
    print('加载了outter3')
    def wrapper3(*args,**kwargs):  # 然后接着执行了wrapper3,
        print('执行了wrapper3')  # 执行wraper3时打印这句话
        res3=func3(*args,**kwargs)  # 然后到了这一步要调用func3,于是执行func3,而根据之前推导的结果我们知道,func3其实就是outter3括号中的index
        return res3
    return wrapper3
@outter1
@outter2
@outter3
def index():  # 执行index函数
    print('from index')  # 打印这句话
index()

#根据执行过成我们可以得到,执行过程中打印的三句话是这样的:
"""
执行了wrapperl
执行了wrapper2
执行了wrapper3
"""

然后我们来看最终的执行结果

小结:多层装饰器在装饰的时候,它的顺序是由下往上,而在执行的时候,它的顺序由上到下。

原文地址:https://www.cnblogs.com/wangnanfei/p/11179912.html