python中的裝飾器,是對「高階函數」的一種延生。使用它能夠對函數進行加強,這樣的方式就好像是OOP中的「裝飾」設計模式所體現出來的效果同樣。
python
1,簡單裝飾器設計模式
先來看一個高階函數的例子,哈,回顧一下
app
而後,把函數「now」用函數「log」給裝飾一下,就像是這樣子:
函數
經過在函數定義時,使用「@fn」來裝飾該函數,這就是python中的裝飾器。
spa
通過上面的例子,同時咱們也能獲得這麼一個結論就是:@log == log(now) 設計
這個,就是python裝飾器最本質的東西!orm
因而,上面的例子,當咱們直接調用「now」函數的時候就會變成這樣:
it
那在調用函數「now」的時候,同時打印出了一條「log」信息,這樣就加強了「now」的功能,這種就稱爲是:裝飾器!方法
2,帶參裝飾器im
那如今,若是你準備在調用裝飾器的時候,同時能夠傳遞一些參數,又該怎麼作呢?
首先,仍是要從高階函數的角度來看,因此,能夠模擬成這樣子:
那上面高階函數的寫法,轉換成裝飾器,就應該是這樣子:
而後,我麼就能夠直接調用函數「now」:
那這樣,是否是就實現了一個帶參數的裝飾器呢?
其實,只要明白一點,裝飾器其實也很好理解。
咱們在函數「now」上,經過增長「@log」,其實就是說:在調用「now」以前,先把「now」當作參數傳遞到「log」方法中執行一次。而後,因爲,咱們後續還須要再次調用「now」,因此,傳遞到「log」內部的「now」必須還得再返回,那這樣的一個過程,就是裝飾器的「執行」過程!
3,正規的寫法
上面實現的裝飾器,在裝飾器的內部咱們直接返回了外部的那個「now」函數,那麼當咱們在外部手動調用「now」函數的時候就會出現函數的返回值變成了它自己,因此咱們應該在裝飾器的內部,顯式的調用一下「now」函數,而且返回它的返回值!
首先,咱們針對不帶參的裝飾器作一個改造。
改造的過程是這樣:當咱們調用裝飾函數「log」的時候,它再也不是直接執行,而是在其內部又定義了一個函數,而後返回這個函數。那這個過程等價於這樣: @log => now = log(now);
如今,「now」函數雖然存在,可是其實它自己已經指向了不一樣的一個函數「wrapper」。而後當你調用這個全新的「now」的時候,其實調用的時候內部的「wrapper」函數,而後該函數打印出對應的信息,同時還調用了「最開始的那個now函數」,爲了可以調用這個「最開始的now 方法」,因此須要在「wrapper」函數中去顯式的調用,同時還要返回它的值,由於這個原本就是「now」方法要返回的內容!
固然,對於帶參的裝飾器,就能夠對應的這麼寫:
帶參數的裝飾器,對於不帶參的而言,只是須要再經過一層函數來包裝一下而言。
備註:必定要認真理解,理解透徹,方成正道!
--------------------------------------------------------華麗的分割線------------------------------------------------
買了本書,應該也快到了 ^_^