python之decorator裝飾器

我們在運行一個函數時,想要動態地給這個函數添加一些功能,又不想在原函數上進行更改,那怎麼做呢?

比如我們想在調用函數時輸出log語句,我們首先想到的是在函數內添加print語句,這個pass掉,不符合前提條件。我們之前還學過高階函數,因爲高階函數可以傳入一個函數,也可以返回一個函數。我們可以利用高階函數,在高階函數裏對原函數進行加工,然後返回加工後的原函數,實現對該函數添加輸出log語句的功能。理論話語不好理解,下面我們看實例操作。

def f1(x):   #原函數
    return x*x
def new_f(f):   #裝飾器
    def fn(a):
        print 'call ' + f.__name__ + '()'
        return f(a)
    return fn
g = new_f(f1)
print g(3)

在上例代碼中,f1() 是原函數,new_f()是高階函數,將原函數 f1() 傳入高階函數中,並在高階函數中定義新函數 fn() ,新函數傳入原函數 f1 中的參數,輸出log語句,並返回原函數結果,最後高階函數 new_f() 返回新函數。這類高階函數被稱爲裝飾器。

解釋裝飾器的工作過程:

將裝飾器調用結果賦值給 g 函數,此時 g 指向 fn;g函數傳入3,即 fn中傳入3,print g(3)即執行 fn函數,先輸出log語句,再輸出原函數結果(因爲fn的return語句是調用原函數),這樣裝飾器就作用完成了。

裝飾器內定義新函數的原因:

裝飾器內假若不定義新函數的話:

def f1(x):
    return x*x
def new_f(f):
    print 'call ' + f.__name__ + '()'
    return f
g = new_f(f1)
print g(3)
#g = new_f(f1)
print g(5)

此時的結果是 ,將變量指向new_f 幾次,就輸出幾次 log 語句,否則輸出結果只是 原函數的值,達不到動態給 f1 函數添加log語句的效果,所以要在裝飾器內定義新函數,將原函數進行包裝。

希望上面我對裝飾器工作過程的解釋能對 還在迷惑裝飾器工作過程的你一些指導,因爲在學習這節內容時我也曾被迷惑其中,學習了已有些時日,這是今天我又翻來複習時,又理解了一次,這次比上次用時少的多。加油呀~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章