zoukankan      html  css  js  c++  java
  • 多层装饰器例子

    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
    """

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

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

  • 相关阅读:
    Django 事务 多表操作
    python oss上传图片
    WARNINGS: ?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
    解决VMware服务起不来的问题
    go-用法
    go-基础语法
    django_filters导入失败
    Git
    windows10安装ubuntu18.04(64位)双系统教程
    Ubuntu系统运行Steam中VR游戏的相关软件环境配置说明
  • 原文地址:https://www.cnblogs.com/wangnanfei/p/11179912.html
Copyright © 2011-2022 走看看