您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Python裝飾器的使用方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“Python裝飾器的使用方法是什么”吧!
1. 什么是裝飾器
對于受到封裝的原函數(shù)比如f來說,裝飾器能夠在f函數(shù)執(zhí)行前或者執(zhí)行后分別運行一些代碼。
2. 裝飾器的結(jié)構(gòu)
裝飾器也是一個函數(shù),它裝飾原函數(shù)f或類cls后,再返回一個函數(shù)g
裝飾一個函數(shù):
def decorator(f): # 定義要返回的函數(shù) def g(): print('函數(shù)f執(zhí)行前的動作') f() print('函數(shù)f執(zhí)行后的動作') return g
裝飾一個類:
def decorator(cls): # 定義要返回的函數(shù) def g(): print('類cls執(zhí)行前的動作') f() print('類cls執(zhí)行后的動作') return g
使用裝飾器很簡單,@+自定義裝飾器 裝飾要想裝飾的函數(shù)。
3. 為什么要這樣
要想理解裝飾器為什么要有這種結(jié)構(gòu),要首先想明白裝飾器的目標是什么。
它的價值在于為原函數(shù)f增加一些行為,前提必須不能破壞函數(shù)f,所以肯定不能改變f的內(nèi)部結(jié)構(gòu),所以只能在調(diào)用f前后定義一些行為。
同時,裝飾器函數(shù)decorator返回值又是什么?你可以思考下,返回一個函數(shù)是再好不過的了,它包裝了原函數(shù)f.
4. 裝飾一個函數(shù)
printStar函數(shù)接收一個函數(shù)f,返回值也是一個函數(shù),所以滿足裝飾器的結(jié)構(gòu)要求,所以printStar是一個裝飾器。
def printStar(f): def g(): print('*'*20) f() print('*'*20) return g
printStar裝飾器實現(xiàn)f函數(shù)執(zhí)行前、后各打印20個*字符。
使用printStar:
@printStar def f(): print('hello world')
調(diào)用:
if __name__ == '__main__': ### 改變函數(shù)功能 f()
打印結(jié)果:
******************** hello world ********************
可以很方便的裝飾要想裝飾的其他函數(shù),如下:
@printStar def g(): print('welcome to Python')
5. 裝飾一個類
除了可以裝飾函數(shù)f外,還可以裝飾類cls,兩者原理都是一樣的。
下面給出一個裝飾器實現(xiàn)單例模式的例子,所謂單例就是類只有唯一實例,不能有第二個。
def singleton(cls): instance = {} def get_instance(*args, **kwargs): if cls not in instance: instance[cls] = cls(*args, **kwargs) return instance[cls] return get_instance
定義字典instance,鍵值對分別為類和實例,這樣確保只cls()一次。
使用裝飾器singleton修飾類:
@singleton class CorePoint: pass
測試:
if __name__ == '__main__': ### 改變類的功能 c1 = CorePoint() c2 = CorePoint() print(c1 is c2) # True
6. 裝飾器層疊
上面原函數(shù)f不僅能被一個裝飾器修飾,還能被n多個裝飾器修飾。
下面再定義一個裝飾器printLine,被修飾函數(shù)執(zhí)行前后打印20個:
def printLine(f): def g(): print('-'*20) f() print('-'*20) return g
使用上文定義好的printStar和printLine同時裝飾函數(shù)f:
@printStar @printLine def f(): print('hello world')
此時再調(diào)用函數(shù)f:
if __name__ == '__main__': ### 改變函數(shù)功能 f()
打印結(jié)果:
******************** -------------------- hello world -------------------- ********************
f被裝飾后,先打印*,再打印 -
層疊多一層,原函數(shù)f就變強大一層。使用裝飾器,還能實現(xiàn)功能抽離,進一步實現(xiàn)松耦合。
7. 溫馨提醒
打印原函數(shù)f的名字__name__,結(jié)果為f
In [1]: def f(): ...: pass In [4]: f.__name__ Out[4]: 'f'
但是,被裝飾后函數(shù)名字f變?yōu)間,這不是我們希望的!
@printStar def f(): pass f() f.__name__ # g
Python提供的解決方案:使用functools模塊中的wraps裝飾器:
from functools import wraps def printStar(f): @wraps(f) def g(): print('*'*20) f() print('*'*20) return g
此時再打印被裝飾后f的名字,顯示f,正常!
到此,相信大家對“Python裝飾器的使用方法是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。