裝飾器(decorator)是一種高級Python語法。裝飾器可以對一個函數(shù)、方法或者類進(jìn)行加工。在Python中,我們有多種方法對函數(shù)和類進(jìn)行加工,比如在Python閉包中,我們見到函數(shù)對象作為某一個函數(shù)的返回結(jié)果。相對于其它方式,裝飾器語法簡單,代碼可讀性高。因此,裝飾器在Python項目中有廣泛的應(yīng)用。
裝飾器最早在Python 2.5中出現(xiàn),它最初被用于加工函數(shù)和方法這樣的可調(diào)用對象(callable object,這樣的對象定義有__call__方法)。在Python 2.6以及之后的Python版本中,裝飾器被進(jìn)一步用于加工類。
裝飾函數(shù)和方法
我們先定義兩個簡單的數(shù)學(xué)函數(shù),一個用來計算平方和,一個用來計算平方差:
代碼如下:
# get square sum
def square_sum(a, b):
return a**2 + b**2
# get square diff
def square_diff(a, b):
return a**2 - b**2
print(square_sum(3, 4))
print(square_diff(3, 4))
在擁有了基本的數(shù)學(xué)功能之后,我們可能想為函數(shù)增加其它的功能,比如打印輸入。我們可以改寫函數(shù)來實現(xiàn)這一點:
代碼如下:
# modify: print input
# get square sum
def square_sum(a, b):
print("intput:", a, b)
return a**2 + b**2
# get square diff
def square_diff(a, b):
print("input", a, b)
return a**2 - b**2
print(square_sum(3, 4))
print(square_diff(3, 4))
我們修改了函數(shù)的定義,為函數(shù)增加了功能。
現(xiàn)在,我們使用裝飾器來實現(xiàn)上述修改:
代碼如下:
def decorator(F):
def new_F(a, b):
print("input", a, b)
return F(a, b)
return new_F
# get square sum
@decorator
def square_sum(a, b):
return a**2 + b**2
# get square diff
@decorator
def square_diff(a, b):
return a**2 - b**2
print(square_sum(3, 4))
print(square_diff(3, 4))
裝飾器可以用def的形式定義,如上面代碼中的decorator。裝飾器接收一個可調(diào)用對象作為輸入?yún)?shù),并返回一個新的可調(diào)用對象。裝飾器新建了一個可調(diào)用對象,也就是上面的new_F。new_F中,我們增加了打印的功能,并通過調(diào)用F(a, b)來實現(xiàn)原有函數(shù)的功能。
定義好裝飾器后,我們就可以通過@語法使用了。在函數(shù)square_sum和square_diff定義之前調(diào)用@decorator,我們實際上將square_sum或square_diff傳遞給decorator,并將decorator返回的新的可調(diào)用對象賦給原來的函數(shù)名(square_sum或square_diff)。 所以,當(dāng)我們調(diào)用square_sum(3, 4)的時候,就相當(dāng)于:
代碼如下:
square_sum = decorator(square_sum)
新聞熱點
疑難解答
圖片精選