裝飾器(可先了解閉包一章再閱讀此章)

一、什麼是裝飾器

裝飾器本質上是一個Python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。

二、怎麼在不改變函數的代碼下爲函數添加額外功能

在這個例子中,我們在不改動函數text代碼的情況下對函數進行添加額外功能,用了閉包的知識,把函數和添加的功能放在內部定義的函數,並且把該函數返回,並且賦值給一個叫innerfunc的變量,而如果此時把代碼修改一下,把innerfunc改成原來的函數名text,會是怎麼樣呢?

可以看出一樣的效果,爲什麼呢,其實當執行到最後第二行的時候,將原來建立的text變量由原來指向的函數空間改指向返回的inner函數內存空間。,而此時的text()執行了函數inner。 

把text=w1(text)註釋掉,然後在text函數(被裝飾的函數)上面加上語法糖@+函數名(給予裝飾的函數)

可以看出,在text函數上加語法糖的效果和text=w1(text)是一樣的。這就是裝飾器的用法。 

三、兩個裝飾器的情況

 

在上面說,@w1等價於text=w1(text),@w2等價於text=w2(text)

也從輸出的123看出是先執行inner1,inner2,再執行text

可是這裏的結果和想象的不一樣,其實它是這樣執行的,它雖然是先執行inner1函數,可是是對用下面的裝飾器進行裝飾,也就是先把text放到w2中進行裝飾,裝飾後此時變成<i>hello</i>,然後再放到w1中進行裝飾,纔得到結果,多個裝飾器也是這樣。

四、裝飾器執行時間

 

@w1等價於text=w1(text),這句語句其實右邊是對w1的調用,所以即使沒有對text進行調用,以及能輸出“裝飾”,證明在text函數執行前,其實text已經被裝飾了。

五、裝飾器對無參函數,有參函數進行裝飾

1.無參函數前面已經舉例了,下面主要對有參函數進行裝飾。

2.對有參函數進行裝飾

可以看出出現一個參數不匹配問題,就是第三行的函數沒有參數

所以使用這樣的函數,在func_in裏面加入倆個參數*args,**kwargs兩個就可以實現不定長參數函數的裝飾

六、對帶有返回值的函數進行裝飾

可以看出裝飾後並沒有返回值,在執行過程中,在@func裝飾後其實test指向了上面的func_in函數,func_in函數沒有返回值,所以返回None

而在這個程序中,第5行用xxx去保存返回的值,然後再返回xxx就可以實現返回了。

七、通用裝飾器(有無返回值,有無參數都能用)

在這個例子中可以看出無論是什麼函數都可以利用func進行裝飾,所以這個是通用裝飾器

八、帶有參數的裝飾器

可以看出裝飾器後面其實是可以加參數的,而這樣的裝飾器需要三層函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章