1. 程式人生 > >裝飾器學習總結

裝飾器學習總結

先看一個例子,知道一個概念。

在這裡插入圖片描述
我兩次定義了test函式最後只執行一次test(),最終的結果如上圖所示。
這個現象叫做函式重寫。
但是這裡想要說明的重點是:
python中函式比如這裡的test()
你可以拆開來看 test + (),test表示函式名,它是一個指向函式在記憶體中首地址的指標。(不知道可不可以這麼說)
()則是代表執行函式的符號。所以當你要呼叫一個函式的時候如果只寫了函式名test卻沒寫()這個函式是不會執行函式體的。
再來分析這張圖:
我們第一次定義了一個test函式,那麼test就指向【紅色箭頭】了紅色方框【可以看做記憶體中的一片地址】,裡面存放了函式體print(‘hello’)。如果這是時候【不考慮下面定義的test】使用test(),那麼結果肯定是hello。但是我們又在下面第二次定義了test函式,因為test只能同一時間指向一個方框,那麼之前的紅色箭頭就會被綠色箭頭代替,這是test就指向了藍色方框裡面的函式體就是print(‘world’),此時再執行test()結果就是world了。

記住上面的分析和結果【就是test最終指向了誰?】,在之下的裝飾器中會經常用到這個結論。

什麼是裝飾器?(標識性符號@)

裝飾器(decorator)是一種高階Python語法。裝飾器可以對一個函式、方法或者類進行加工。在Python中,我們有多種方法對函式和類進行加工,比如在Python閉包中,我們見到函式物件作為某一個函式的返回結果。相對於其它方式,裝飾器語法簡單,程式碼可讀性高。因此,裝飾器在Python專案中有廣泛的應用。

裝飾器最早在Python 2.5中出現,它最初被用於加工函式和方法這樣的可呼叫物件(callable object,這樣的物件定義有call方法)。在Python 2.6以及之後的Python版本中,裝飾器被進一步用於加工類

為什麼要用裝飾器?、

1,避免寫冗餘的程式碼
2,可以在不更改原始碼的情況下,對程式碼增加功能。因為一般專案中都要遵守開放封閉原則,就是原來的程式碼最後不要動而是通過增加程式碼來實現對原來功能的增加改良等等。

裝飾器的幾種形式以及執行的順序

1.對不帶引數的函式進行裝飾(最基本的):

在這裡插入圖片描述
所以此時再執行f1()這句話的時候,其實是先執行inner,再在inner裡面執行func,由func呼叫print(‘f1’)。
看起來就像f1毫無變化就實現了別的功能!!!

上面綠色方框裡面提到了一個新的概念“閉包”,什麼是閉包呢?
閉包實質就是函式巢狀,並且函式裡面的函式用到了外面一層函式的變數。

這裡我們在函式oueter內又定義了一個inner()函式,並且inner()函式裡面用到了outer函式的變數func。

需要注意的是outer函式最後一行的return inner這句話,這句話一定要寫,它讓你執行outer函式的時候返回inner函式的引用,然後你才能繼續使用inner函式。

2.對帶引數的函式進行裝飾:

理解了第一種這一種也是很簡單的。
在這裡插入圖片描述

上面這個的侷限性就是函式的引數個數固定死了,不能多不能少,然而實際專案肯定不合適。同時又是函式還有返回值,這個你也不能遺漏,所以對上圖的函式進一步修改。

 這時候就要用*args和**kwargs來幫忙了,`我這裡當初沒使用*kwargs只用了*args`

程式碼如下:

3.對帶不定長引數和返回值的函式以及帶引數的@的裝飾:

在這裡插入圖片描述

4.一個函式上有兩個@

在這裡插入圖片描述

5.類裝飾器

在這裡插入圖片描述
類裝飾器同理

@等效 fx1=Lei(fx1)
但是要呼叫的話一定要定義__call__方法,同時,self.fx1後面一定要加括號!!!!!!

否則:
在這裡插入圖片描述

目前就這麼多了。 繼續學習