Python中的裝飾器是Python語言中的一個重要組成部分,屬於python語法糖一大致現。python
裝飾器能夠一言以蔽之:緩存
裝飾器本質上是一個 Python 函數或類,它可讓其餘函數或類在不須要作任何代碼修改的前提下增長額外功能,裝飾器的返回值也是一個函數/類對象。它常常用於有切面需求的場景,好比:插入日誌、性能測試、事務處理、緩存、權限校驗等場景,裝飾器是解決這類問題的絕佳設計。有了裝飾器,咱們就能夠抽離出大量與函數功能自己無關的雷同代碼到裝飾器中並繼續重用。app
本來定義了一個foo函數,爲了給該函數添加日誌功能,在其中添加了一行代碼;以下圖所示:
函數
若是函數其它也有相似的需求,怎麼作?再寫一個日誌打印語句在函數裏?這樣就形成大量雷同的代碼。爲了減小重複寫代碼,進入第二階段。性能
從新定義一個函數用於專門處理日誌 ,日誌處理完以後再執行真正的業務代碼;以下圖所示:
測試
此時調用的時候再也不是調用真正的業務邏輯foo函數,而是換成了use_logging函數,這就破壞了原有的代碼結構;而且如今須要每次都把原來的foo函數做爲參數傳遞給use_logging函數。爲了進一步簡化,進入第三階段。設計
use_logging就是一個裝飾器,它一個普通的函數,它把執行真正業務邏輯的函數foo包裹在其中,看起來像foo被use_logging裝飾了同樣;use_logging 返回的是一個wrapper函數;以下圖所示:
3d
裝飾器的做用就在於上述第三階段,不過爲了簡介,引入@語法糖的操做,進入第四階段。日誌
使用@操做,能夠省去foo = use_logging(foo)這一句了,直接調用 foo() 便可獲得想要的結果;以下圖所示:
對象
能夠看到,foo() 函數不須要作任何修改,只需在定義的地方加上裝飾器,就能夠豐富它的功能;
此外,定義了一個foo_1()函數,繼續調用裝飾器來修飾foo_1()函數,起到了相似的效果。