zoukankan      html  css  js  c++  java
  • 多层装饰器叠加装饰

    多层装饰器叠加

    加载顺序自下而上,执行顺序自上而下。

    def wrapper1(func1):  # func1的内存地址是inner2
        print('from func1',func1)
        def inner1(*args,**kwargs):
            print('这是inner1.被装饰函数执行前')
            res1 = func1(*args,**kwargs)
            print('这是inner1.被装饰函数执行后')
            return res1
        return inner1
    
    def wrapper2(func2):  # func2的内存地址是inner3
        print('from func2',func2)
        def inner2(*args,**kwargs):
            print('inner2,被装饰函数执行前')
            res2 = func2(*args,**kwargs)
            print('inner2,被装饰函数执行后')
            return res2
        return inner2
    
    def wrapper3(func3):  # func3 的内存地址是total
        print('from func3',func3)
        def inner3(*args,**kwargs):
            print('inner3,被装饰函数执行前')
            res3 = func3(*args,**kwargs)
            print('inner3,被装饰函数执行后')
            return res3
        return inner3
    
    @wrapper1  # wrapper2 = wrapper1(wrapper2) = inner1的内存地址
    @wrapper2  # wrapper3 = wrapper2(wrapper3) = inner2的内存地址
    @wrapper3  # total = wrapper3(total) = inner3的内存地址
    def total(a, b):
        print(a+b)
        return a+b
    

    上述叠加多个装饰器的语义本质其实就是:

    total = wrapper1(wrapper2(wrapper3(total)))
    

    不调用被装饰函数的执行结果:

    from func3 <function total at 0x0000000002798790>
    from func2 <function wrapper3.<locals>.inner3 at 0x0000000002798820>
    from func1 <function wrapper2.<locals>.inner2 at 0x00000000027988B0>
    

    @wrapper3等于wrapper(total),加括号会直接调用该函数,所以装饰器的第一层代码会执行。

    调用结果:

    total()
    
    from func3 <function total at 0x0000000002788790>
    from func2 <function wrapper3.<locals>.inner3 at 0x0000000002788820>
    from func1 <function wrapper2.<locals>.inner2 at 0x00000000027888B0>
    这是inner1.被装饰函数执行前
    这是inner2,被装饰函数执行前
    这是inner3,被装饰函数执行前
    这里是原total
    这是inner3,被装饰函数执行后
    这是inner2,被装饰函数执行后
    这是inner1.被装饰函数执行后
    
  • 相关阅读:
    Object.defineProperty 监听对象属性变化
    Object.create(null) 和 {} 区别
    Vue 源码 基础知识点
    js setTimeout和setInterval区别
    Fiddler抓包工具使用方法
    使用 Jmeter 做 Web 接口测试
    Python 操作 SQL 数据库 (ORCAL)
    python连接MySQL数据库问题
    抓包工具Charles基本用法
    Python数据分析之pandas学习
  • 原文地址:https://www.cnblogs.com/ChiRou/p/13408281.html
Copyright © 2011-2022 走看看