# 一.参加多个装饰器的加载,运行分析(了解)
def deco1(func1):  # func1=wrapper2的内存地址
    def wrapper1(*args, **kwargs):
        print('正在运行====>deco1.wrapper1')
        res1 = func1(*args, **kwargs)
        return res1
    return wrapper1
def deco2(func2):  # func2=wrapper3的内存地址
    def wrapper2(*args, **kwargs):
        print('正在运行====>deco2.wrapper2')
        res2 = func2(*args, **kwargs)
        return res2
    return wrapper2
def deco3(x):
    def outter3(func3):  # func3=被装饰对象index函数(第39行代码)的内存地址(这是要掌握的一个本质问题)
        def wrapper3(*args, **kwargs):
            print('正在运行====>deco3.outter3.wrapper3')
            res3 = func3(*args, **kwargs)
            return res3
        return wrapper3
    return outter3
# 加载顺序自下而上
@deco1  # index=decco1(wrapper2的内存地址) ---->index=wrapper1的内存地址
@deco2  # index=deco2(wrapper3的内存地址)------>index=wrapper2的内存地址
@deco3(111)  # ===>@outter3--->index=wrapper3(index)---->最得到的是wrapper3的内存地址
def index(x, y):  # 无论外面套多少层,最终还是用index()偷梁换柱成wrapper()
    print('from index %s:%s' % (x, y))
# index(1,2)
print(index)  # 这里最后得到的应该是deco1下对应的wrappe1的内存地址
# 执行顺序:自上而下,即wrapper1-->wrapper2-->wrapper3(index)            *******重点********
index(12)  # wrapper1
# 先运行wrapper1,打印出内容后,调用到func1(也就是wrapper2)
# 运行wrapper2,打印出内容后,调用func2(也就是wrapper3)
# 运行wrapper3,打印内容,调用funcu3(也就是index)
# 运行index,也就是打印出(from index x,y的内容38行)
# wrapper3结束
# wrapper2结束
# wrapper1结束