python的語法糖就是對指定的目標函數進行裝飾。
要想先了解裝飾器,就必須先知道閉包
python函數的閉包實際上就是一個函數,其傳入的參數是一個函數,返回的仍然是一個函數
例如:
import time def after_add(func): def add_thing(): print('----裝飾前------') func() print('----裝飾后------') return add_thing def add_1(): print((time.strftime('%H:%M:%S',time.localtime(time.time())))) if __name__== '__main__': add_2 = after_add(add_1) add_2()
這里after_add就形成了一個閉包
那如何形成一個裝飾器?裝飾器其實跟閉包相似,只是裝飾器沒有將新函數傳給一個變量,然后再調入,而是一氣呵成
裝飾器相當於 add_2 = after_add(add_1)
所以代碼可以等價於
import time def after_add(func): def add_thing(): print('----裝飾前------') func() print('----裝飾后------') return add_thing @after_add def add_1(): print((time.strftime('%H:%M:%S',time.localtime(time.time())))) if __name__== '__main__': add_1()
這里就跟前面的閉包一樣,就跟 add_2 = after_add(add_1)這樣分析,先進入after_add(),先定義了函數,然后再得到新函數,接着再調用得到的函數,所以最后才打印這個結果
如果像這樣
import time
def after_add(func):
print(11)
def add_thing():
print('----裝飾前------')
func()
print('----裝飾后------')
return add_thing
@after_add
def add_1():
print((time.strftime('%H:%M:%S',time.localtime(time.time()))))
if __name__== '__main__':
add_1()
加入print(11),所以先打印了11
記住兩個原則:
1、裝飾器在函數調用之前被增強
2、相同的函數只被增強一次
下面看一下帶參數的裝飾器
目標函數的參數供自己使用,就例如
import time def say_thing(func): def say_say(name): print("Hello") func(name) return say_say @say_thing def say_name(name): print(name) say_name('Li Ming')
這里注意say_say這里也需要帶參數,因為裝飾器最后調用的是增強后的say_say,需要通過增強函數將參數傳給目標函數.
這里還注意一點就是如果有多個裝飾器,它是從內往外增強的