一文詳解如何創(chuàng)建自己的Python裝飾器
python裝飾器在平常的python編程中用到的還是很多的,在本篇文章中我們先來介紹一下python中最常使用的@staticmethod裝飾器的使用。
之后,我們會(huì)使用兩種不同的方式來創(chuàng)建自己的自定義python裝飾器以及如何在其他地方進(jìn)行調(diào)用。
1、@staticmethod
@staticmethod是python開發(fā)者經(jīng)常用來在一個(gè)類中聲明該函數(shù)是一個(gè)靜態(tài)函數(shù)時(shí)使用到的裝飾器,比如創(chuàng)建一個(gè)HelloWorld的python類,并且在其中使用該靜態(tài)裝飾器聲明其中的函數(shù)。
class HelloWorld(): def __init__(self): super(HelloWorld, self).__init__() @staticmethod def print_hello_world(): print('welcome to hello world!')
@staticmethod裝飾器一般是對(duì)于一些公共的函數(shù),或是工具函數(shù)之類的函數(shù)進(jìn)行聲明,聲明之后就不會(huì)將當(dāng)前python類中的初始化變量信息等傳入到該函數(shù)中,可以看到print_hello_world函數(shù)并沒有self作為參數(shù)變量。
接下來可以在初始化@staticmethod聲明的函數(shù)所在的類HelloWorld,并且調(diào)用print_hello_world函數(shù)。
hello_world = HelloWorld() hello_world.print_hello_world()
會(huì)發(fā)現(xiàn)控制臺(tái)直接打印出了welcome to hello world!這行字符串。
實(shí)際上在python中的函數(shù)上面加入裝飾器只是為了在執(zhí)行當(dāng)前函數(shù)的邏輯之前去執(zhí)行一些我們需要執(zhí)行的業(yè)務(wù)功能,這樣的操作我們通過自定義自己的裝飾器也能夠?qū)崿F(xiàn)同樣的效果。
2、自定義裝飾器
其實(shí),自定義裝飾器的過程也比較簡(jiǎn)單,就是我們平常用到的函數(shù)或者python類的寫法就能夠?qū)崿F(xiàn)。
自己實(shí)現(xiàn)裝飾器主要有兩種方式,一種是通過class類的方式來實(shí)現(xiàn)的,另外一種則是通過python函數(shù)嵌套的方式來實(shí)現(xiàn)的,下面我們先來通過第一種的方式來實(shí)現(xiàn),也就是通過python類的方式來實(shí)現(xiàn)。
python類實(shí)現(xiàn)裝飾器
用python類來實(shí)現(xiàn)裝飾器時(shí),必須明白一個(gè)知識(shí)點(diǎn)。python類中實(shí)際上默認(rèn)有一個(gè)成員函數(shù)__call__,這個(gè)成員函數(shù)就是這個(gè)類被調(diào)用時(shí)的函數(shù)對(duì)象,若是需要自定義裝飾器實(shí)際上就是在python類的__call__函數(shù)中來實(shí)現(xiàn)裝飾器主要業(yè)務(wù)邏輯實(shí)現(xiàn)的。
class print_message(object): def __init__(self, function_): self.function_ = function_ def __call__(self): # TODO:這里實(shí)際上是對(duì)傳入的函數(shù)返回值進(jìn)行的裝飾,可以理解成是一種回調(diào)。 print('裝飾器,{}'.format(self.function_()))
注意:在下面這行代碼塊中一定要注意self.function_是一個(gè)函數(shù)對(duì)象,而self.function_()是一個(gè)函數(shù)返回值得效果。
print('裝飾器,{}'.format(self.function_()))
這樣,我們通過python類就已經(jīng)實(shí)現(xiàn)了python裝飾器的效果,使用一個(gè)函數(shù)來試驗(yàn)一下效果。
@print_message def hello_world(): return 'hello world!' hello_world()
調(diào)用使用了@print_message裝飾器的函數(shù),它會(huì)返回我們預(yù)期的一個(gè)函數(shù)結(jié)果的打印。
# 裝飾器,hello world!
python函數(shù)嵌套實(shí)現(xiàn)裝飾器
上面的操作過程是通過重新定義了一個(gè)python類來實(shí)現(xiàn)裝飾器的效果的,這里再使用函數(shù)嵌套的方式來實(shí)現(xiàn)。
因?yàn)椋覀兌贾涝趐ython中函數(shù)中再可以嵌套函數(shù)的,在函數(shù)中嵌套一個(gè)函數(shù)時(shí)上層的函數(shù)相對(duì)于子函數(shù)來說就是它的一個(gè)父級(jí)對(duì)象。
@print_message2 @print_message def hello_world3(): return 'hello world!' hello_world3() # 裝飾器,hello world! # 裝飾器2,None
使用函數(shù)嵌套的方式同樣實(shí)現(xiàn)了函數(shù)的裝飾器的效果,那么思考一下若是有兩個(gè)裝飾器可以在同一個(gè)函數(shù)中使用嗎?
多個(gè)裝飾器調(diào)用
話不多說,為了證明兩個(gè)裝飾器能不能放到一個(gè)函數(shù)上面使用,我們直接試一下效果如何。
@print_message2 @print_message def hello_world3(): return 'hello world!' hello_world3() # 裝飾器,hello world! # 裝飾器2,None
從返回結(jié)果來看,首先是兩個(gè)裝飾器都是執(zhí)行了,從數(shù)據(jù)結(jié)果打印的順序來看自定義的裝飾器的執(zhí)行順序應(yīng)該是從距離函數(shù)最近的裝飾器開始執(zhí)行的,也就是從下往上的順序挨個(gè)執(zhí)行該函數(shù)上面的裝飾器的.
另外,裝飾器2的結(jié)果為None,這是為什么呢?
因?yàn)?第一個(gè)裝飾器執(zhí)行的時(shí)候,它的參數(shù)應(yīng)該是hello_world函數(shù)本身,但是當(dāng)?shù)诙€(gè)裝飾器執(zhí)行的時(shí)候第一個(gè)裝飾器并沒有返回結(jié)果知識(shí)做了打印,這個(gè)時(shí)候第二個(gè)裝飾器接收到的參數(shù)自然就是None了。
3、帶參數(shù)的裝飾器
說實(shí)話帶參數(shù)的裝飾器在python中我見到的不多,不多在java中幾乎只要是裝飾器都是可以加參數(shù)執(zhí)行的。
還是來介紹一下,算是屬于擴(kuò)展知識(shí)吧,既然已經(jīng)看到了這里,不妨再多掌握個(gè)小技能吧,哈哈~
我們使用pytgon嵌套的函數(shù)功能來實(shí)現(xiàn)這個(gè)帶參數(shù)的裝飾器吧,個(gè)人覺得這種方便一些。
def header(message): def decorator(function_): def wrapper(): return '帶參數(shù)的裝飾器,參數(shù):{0},{1}'.format(message, function_()) return wrapper return decorator @header('Python 集中營') def hello_world4(): return 'hello world!' print(hello_world4()) # 帶參數(shù)的裝飾器,參數(shù):Python 集中營,hello world!
OK,帶參數(shù)的裝飾器果然生效了,給@header加上參數(shù)@header(‘Python 集中營’),上面裝飾器直接使用三層函數(shù)的嵌套來實(shí)現(xiàn)的。
第一層函數(shù)參數(shù)是我們需要自定義給裝飾器傳入的參數(shù),第二層則是傳入的已經(jīng)添加了裝飾器的函數(shù)本身,到了第三層才是真正的處理裝飾器自己的業(yè)務(wù)邏輯的。
到此這篇關(guān)于一文詳解如何創(chuàng)建自己的Python裝飾器的文章就介紹到這了,更多相關(guān)Python裝飾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 利用百度API進(jìn)行淘寶評(píng)論關(guān)鍵詞提取
這篇文章主要介紹了python 利用百度API進(jìn)行淘寶評(píng)論關(guān)鍵詞提取,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-03-03pandas.DataFrame中提取特定類型dtype的列
本文主要介紹了pandas.DataFrame中提取特定類型dtype的列,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02Python求出0~100以內(nèi)的所有素?cái)?shù)
質(zhì)數(shù)又稱素?cái)?shù)。一個(gè)大于1的自然數(shù),除了1和它自身外,不能被其他自然數(shù)整除的數(shù)叫做質(zhì)數(shù);否則稱為合數(shù)。下面小編給大家?guī)砹薖ython求出0~100以內(nèi)的所有素?cái)?shù)實(shí)例代碼,需要的朋友參考下2018-01-01python使用form-data形式上傳文件請(qǐng)求的方法
Python中的multipart/form-data是一種HTTP POST請(qǐng)求的數(shù)據(jù)格式,用于上傳文件或二進(jìn)制數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于python使用form-data形式上傳文件請(qǐng)求的相關(guān)資料,需要的朋友可以參考下2023-04-04python pyg2plot的原理知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理的是一篇關(guān)于python pyg2plot的原理知識(shí)點(diǎn)總結(jié)內(nèi)容,有興趣的朋友們可以參考下。2021-02-02Python attrs提高面向?qū)ο缶幊绦试敿?xì)
Python是面向?qū)ο蟮恼Z言,一般情況下使用面向?qū)ο缶幊虝?huì)使得開發(fā)效率更高,軟件質(zhì)量更好,并且代碼更易于擴(kuò)展,可讀性和可維護(hù)性也更高,但是Python的類寫起來是真的累,這是可以在創(chuàng)建類的時(shí)候自動(dòng)添加上attrs模塊,下面文章我們就來介紹這個(gè)東西,需要的朋友可參考一下2021-09-09Python按照某列內(nèi)容對(duì)兩個(gè)DataFrame進(jìn)行合并操作方法
這篇文章主要給大家介紹了關(guān)于Python按照某列內(nèi)容對(duì)兩個(gè)DataFrame進(jìn)行合并操作的相關(guān)資料,文中通過代碼示例介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08Python如何創(chuàng)建裝飾器時(shí)保留函數(shù)元信息
這篇文章主要介紹了Python如何創(chuàng)建裝飾器時(shí)保留函數(shù)元信息,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-08-08