1. 程式人生 > >python3-多個裝飾器的執行順序

python3-多個裝飾器的執行順序

裝飾器的本質是一個函式,可解理成先組裝出一個函式,然後呼叫。


【例】: 

def dec1(func):
    print("HHHA:0====>")
    def one():
        print("HHHA:0.1====>")
        func()
        print("HHHA:0.2====>")
    return one


def dec2(func):
    print("HHHB:0====>")
    def two():
        print("HHHB:0.1====>")
        func()
        print("HHHB:0.2====>")
    return two


def dec3(func):
    print("HHHC:0====>")
    def three():
        print("HHHC:0.1====>")
        func()
        print("HHHC:0.2====>")
    return three


@dec1
@dec2
@dec3
def test():
    print("HHHD:0====>test")


print("HHHH:0====>")
test()

輸出:

HHHC:0====>
HHHB:0====>
HHHA:0====>
HHHH:0====>
HHHA:0.1====>
HHHB:0.1====>
HHHC:0.1====>
HHHD:0====>test
HHHC:0.2====>
HHHB:0.2====>
HHHA:0.2====>

請注意:以HHHH:0====>為界,前面為裝飾,後面為呼叫。

【組裝階段】:  

    HHHC:0====>
    HHHB:0====>
    HHHA:0====>

可看出組裝階段是從下到上(即從最靠近被裝飾的函式開始)。

【呼叫階段】:

    HHHA:0.1====>
    HHHB:0.1====>
    HHHC:0.1====>
    HHHD:0====>test
    HHHC:0.2====>
    HHHB:0.2====>
    HHHA:0.2====>

可看出執順序是從外到內然後到外,等效於以下包含關係:

{
    print("HHHA:0.1====>") //最外層
    {
        print("HHHB:0.1====>") //中間層
        {
            print("HHHC:0.1====>") //內層
            {
                test() //被裝飾者
                {
                   print("HHHD:0====>test")
                }
            }
            print("HHHC:0.2====>")
        }
        print("HHHB:0.2====>")
    }
    print("HHHA:0.2====>")
}

被裝飾的函式是一個妹子,裝飾器是衣服。“辦事情”的時候得依次把外套、襯衣、內衣脫掉,事情辦完了還要依次把內衣、襯衣、外套穿上。距離“妹子”越近的裝飾器代表越貼身的衣服。

 

【帶引數的裝飾器】:

如果修飾器本身需要傳入引數, 比如,要自定義log的文字:

def log(text):
    print("HHHA:0====>")
    def decorator(func):
        print("HHHA:0.1====>")
        def wrapper(*args, **kw):
            print("HHHA:0.1.1====>")
            return func(*args, **kw)
        print("HHHA:0.2====>")
        return wrapper
    print("HHHA:1====>")
    return decorator


@log('execute')
def now():
    print('HHHB:=====>test')


now()

輸出:

HHHA:0====>
HHHA:1====>
HHHA:0.1====>
HHHA:0.2====>
HHHA:0.1.1====>
HHHB:=====>test