装饰器
加载顺序从下至上 执行顺序从上至下
'''
多层装饰器
'''
def deco1(func): #func=deco2
    def wrapper1(*args, **kwargs):
        '''this is wrapper1'''
        print('start 1')
        result = func(*args, **kwargs)# wrapper2()
        print('end   1')
        return result
    return wrapper1
def deco2(func):#func=deco1
    def wrapper2(*args, **kwargs):
        '''this is wrapper2'''
        print('start 2')
        result = func(*args, **kwargs)# wrapper3()
        print('end   2')
        return result
    return wrapper2
def deco3(func):#func=foo
    def wrapper3(*args, **kwargs):
        '''this is wrapper3'''
        print('start 3')
        result = func(*args, **kwargs)#wrapper1()
        print('end   3')
        return result
    return wrapper3
@deco1##deco1(deco2(deco3(foo)))
@deco2 #deco2(deco3(foo))
@deco3 #deco3(foo)
def foo(x, y):
    '''this is foo'''
    return x * y
print(foo(8, 9))#wrapper1(wrapper2( wrapper3(foo)))执行从外往内
'''
输出结果:
    start 1
    start 2
    start 3
    end   3
    end   2
    end   1
    72
'''
'''
装饰的过程:
    wrapper3 = deco3(foo)
    wrapper2 = deco2(wrapper3)
    wrapper1 = deco1(wrapper2)
    foo = wrapper1
执行的过程:正好和装饰的过程相反。
        foo(8, 9)--->wrapper1(8, 9)--->deco1(wrapper2)(8, 9)--->
                                                                |
                                                                v
        deco1( deco2( deco3(foo) ) )(8, 9)<---deco1( deco2(wrapper3) )(8, 9)
        类比穿衣服,穿(装饰)的时候从里往外一层套一层,脱(执行)的时候从外到里一层一层脱。
'''