標籤:python 出錯 意思 style 問題 也有 func csdn fun
出處
為什麼需要使用裝飾器呢?其實很多人學習python之後都會問這個問題。
這一次,我來深入地學習一下什麼是裝飾器,以及為什麼需要它。
其實這個裝飾器就是我們這樣的程式員太“懶”了,基本上什麼事情都想少做,追求是DRY,那麼什麼是DRY,如下:
DRY(Don‘t repeat yourself
),字面意思來看:"不要重複自己"。強調的意思就是在進行編程時相同的代碼不要重複寫,最好唯寫一次,然後可以在其他地方直接引用。如此一來,可以提高代碼重用率,縮減代碼量,同時也有助於提高代碼的可讀性和可維護性。當需要做出更改時,只需要更改一個地方即可。
有了這個指導思想,就很明白了,就是少寫代碼,裝飾器的目的也就是少寫代碼,複用代碼。
複用代碼有很多種方式,比如物件導向裡的繼承,虛函數等,但是想在函數層面來複用代碼,有什麼方法呢?
一般情況之下,就是函數中調用另一個函數來達到繼承和複用。函數裡調用別的函數,如下面的例子:
1 #python 3.62 def add():3 return 1 + 14 5 def sub():6 return 2 -17 8 print(add())9 print(sub())
輸出如下:
2
1
如果這時,我們想把每個函數添加一行星號列印輸出,以便分隔開來,更好看一些,我們往往會這樣做修改,
每個函數裡添加一行星號就行了,修改如下:
1 #python 3.6 2 def add(): 3 print(‘*************************************‘) 4 return 1 + 1 5 6 def sub(): 7 print(‘*************************************‘) 8 return 2 -1 9 10 print(add())11 print(sub())
輸出如下:
*************************************
2
*************************************
1
當我們只有兩個函數時,這樣修改很快的,並且很快就完成工作了,但是如果有1000個這樣函數呢?那麼是否需要添加1000遍?
如果你每個函數去添加一個也是可以完成任務的,但是有想法,或者更聰明的辦法,就不是這樣了。能否不修改原來的函數,即是原來的函數代碼一點都不改變,又能增加這樣的功能呢?答案是可以的,如下修改:
1 #python 3.6 2 def add(): 3 return 1 + 1 4 5 def sub(): 6 return 2 -1 7 8 #定義一個新的函數 9 def printStar(func):10 print(‘*************************************‘)11 return func()12 13 print(printStar(add))14 print(printStar(sub))
輸出如下:
*************************************
2
*************************************
1
在這裡增加了一個函數,這個函數接收一個函數對象作為參數,這樣就不需要修改原來的函數,達到原來穩定並且測試通過的代碼不作任何修改,減少出錯的風險,特別已經上線啟動並執行系統,更是如此;或者像8代單傳的代碼,沒有人敢去修改它,否則領導會怪你,怎麼樣把產品越改越差,本來是請你來做好產品的,結果不行。做到這一步,就結束了嗎?還不行啊,因為每個調用這個函數的地方都需要修改,因此再繼續修改,結果改成這樣:
1 #python 3.6 2 #定義一個新的函數 3 def printStar(func): 4 print(‘*************************************‘) 5 return func() 6 7 @printStar 8 def add(): 9 return 1 + 110 11 def sub():12 return 2 -113 14 15 16 print(add)17 print(printStar(sub))
輸出結果如下:
*************************************
2
*************************************
1
這裡發現調用add方法,還是不一樣,繼續修改,代碼如下:
1 #python 3.6 2 #定義一個新的函數 3 def printStar(func): 4 def f(): 5 print(‘*************************************‘) 6 return func() 7 return f 8 9 @printStar10 def add():11 return 1 + 112 13 def sub():14 return 2 -115 16 print(add())17 18 sub = printStar(sub)19 print(sub())
輸出結果如下:
*************************************
2
*************************************
1
到這裡,可以發現使用嵌套函數來實現,就可以返回一個可調用的對象,這樣更加完美了。
1 #python 3.6 2 #定義一個新的函數 3 def printStar(func): 4 def f(): 5 print(‘*************************************‘) 6 return func() 7 return f 8 9 @printStar10 def add():11 return 1 + 112 13 @printStar14 def sub():15 return 2 -116 17 print(add())18 19 print(sub())
在這裡可以發現這兩段代碼是相等的:
def sub():
return 2 -1
sub = printStar(sub)
和
@printStar
def sub():
return 2 -1
由此可見@printStar是一個文法改變,它的目標就是實現不修改原來函數的代碼,又可以複用原來的函數並且作出修改,也稱作為元編程,並且裝飾器函數可以複用,實現共用的目標。
(轉)python裡為什麼需要使用裝飾器(decorator)