python 多個裝飾器的調用順序

前言

裝飾器是程序開發中常常會用到的一個功能,也是python語言開發的基礎知識,若是可以在程序中合理的使用裝飾器,不只能夠提升開發效率,並且可讓寫的代碼看上去顯的高大上^_^html

使用場景

能夠用到裝飾器的地方有不少,簡單的舉例如如下場景python

  • 引入日誌segmentfault

  • 函數執行時間統計緩存

  • 執行函數前預備處理session

  • 執行函數後清理功能python2.7

  • 權限校驗等場景函數

  • 緩存tornado

裝飾器案例

def user_login(fun):
    def islogin(request,*args,**kwargs):
        context = {}
        if request.session.has_key('uname'):
            context['uname'] = request.session.get('uname')
        else:
            context['uname'] = 'None'
        return fun(request,context,*args,**kwargs)
    return islogin

@user_login
def ucOrder(request,context,pIndex):
    '''
    獲取數據
    處理數據
    傳遞到頁面上去

以上是一個簡單電商應用中使用裝飾器的案例,其中 ucOrder函數是是用戶須要登陸後才能被執行到的。若是不使用裝飾器的話,普通的作法多是在 ucOrder中寫一堆校驗代碼來判斷用戶是否登陸,而後決定後面的執行邏輯,這樣比較麻煩。.net

那麼使用裝飾器以後就比較簡單了,只須要按照裝飾器的使用格式,在ucOrder函數上面加上@user_login,那麼python解釋器在運行的時候,就會從上到下解釋代碼,先執行user_login函數,而且將ucOrder做爲user_login函數的參數傳入進去,即等價於user_login(ucOrder),這樣就起到了一個校驗用戶是否登陸,從而決定是否執行ucOrder函數的功能日誌

多個裝飾器使用的調用順序

def one(func):
    print('----1----')
    def two():
        print('----2----')
        func()
    return two

def a(func):
    print('----a----')
    def b():
        print('----b----')
        func()
    return b

@one
@a
def demo():
    print('----3----')

demo()

執行結果:

/usr/bin/python2.7 /home/python/Desktop/tornadoProject/one.py
----a----
----1----
----2----
----b----
----3----

能夠從執行結果中看到,若是是使用多個裝飾器,它的執行順序仍是有點怪異的的,爲何會這樣呢?

關於這個問題,有更好的文章能夠解釋,具體見如下連接

Python 裝飾器執行順序迷思

其餘參考文章:
理解 Python 裝飾器看這一篇就夠了

相關文章
相關標籤/搜索