python:語法糖和裝飾器
阿新 • • 發佈:2021-06-24
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,需要通過增強函式將引數傳給目標函式.
這裡還注意一點就是如果有多個裝飾器,它是從內往外增強的