python裝飾器代碼解析
1.裝飾器通用模型
def wrapper(fn): ? ? def inner(*args, **kwargs): ? ? ? ? ret = fn(*args, **kwargs) ? ? ? ? return ret ? ? return inner
裝飾器幾個(gè)關(guān)鍵點(diǎn):
- 1.函數(shù)可以當(dāng)參數(shù)傳遞
- 2.函數(shù)可以作為返回值進(jìn)行返回
- 3.函數(shù)名稱可以當(dāng)成變量一樣進(jìn)行賦值操作
裝飾器本質(zhì)上是個(gè)閉包,在不改變?cè)泻瘮?shù)調(diào)用的情況下,給函數(shù)增加新的功能
舉個(gè)例子:
def admin(game):
? ? def inner(*args, **kwargs): ?# inner添加了參數(shù),args 一定是個(gè)元組 kwargs 一定是字典
? ? ? ? print('打開Wg')
? ? ? ? result = game(*args, **kwargs) ?# * ** 表示把a(bǔ)rgs元組和kwargs打散成位置參數(shù),關(guān)鍵字參數(shù)傳遞進(jìn)去
? ? ? ? print('關(guān)閉Wg')
? ? ? ? return result
? ? return inner
@admin
def play_dnf(username, password):
? ? print(f'開始玩DNF,賬號(hào):{username},密碼:{password}')
? ? print('刀斬肉身,心斬靈魂')
? ? return '掉落:戮蠱的哀鳴炮'
@admin
def play_wow(race, occupation, server_name, camp):
? ? print(f'開始玩魔獸世界,種族:{race},職業(yè):{occupation},服務(wù)器:{server_name},陣營:{camp}')
? ? print('為了辛多雷的榮耀')
? ? return '掉落:灰燼使者'
if __name__ == '__main__':
? ? ret1 = play_dnf('大馬猴', '888888')
? ? print(ret1)
? ? ret2 = play_wow('血精靈', '圣騎士', '回音山', '部落')
? ? print(ret2)這代碼還是很好懂的,我就不解釋了,然后是執(zhí)行結(jié)果如下:
python demo.py
打開Wg
開始玩DNF,賬號(hào):大馬猴,密碼:888888
刀斬肉身,心斬靈魂
關(guān)閉Wg
掉落:戮蠱的哀鳴炮
打開Wg
開始玩魔獸世界,種族:血精靈,職業(yè):圣騎士,服務(wù)器:回音山,陣營:部落
為了辛多雷的榮耀
關(guān)閉Wg
掉落:灰燼使者Process finished with exit code 0
2.多個(gè)裝飾器裝飾的函數(shù)執(zhí)行
一個(gè)函數(shù)被多個(gè)裝飾器裝飾,又將如何執(zhí)行呢?
def wrapper1(fn):
? ? def inner(*args, **kwargs):
? ? ? ? print('這是w1進(jìn)入')
? ? ? ? ret = fn(*args, **kwargs)
? ? ? ? print('這是w1出去')
? ? ? ? return ret
? ? return inner
def wrapper2(fn):
? ? def inner(*args, **kwargs):
? ? ? ? print('這是w2進(jìn)入')
? ? ? ? ret = fn(*args, **kwargs)
? ? ? ? print('這是w2出去')
? ? ? ? return ret
? ? return inner
@wrapper1
@wrapper2
def target():
? ? print('我是目標(biāo)')
if __name__ == '__main__':
? ? target()直接給出執(zhí)行順序:
一個(gè)函數(shù)被多個(gè)裝飾器裝飾的執(zhí)行順序
# w1 w2 target w2 w1
3.帶參數(shù)的裝飾器
裝飾器的語法允許我們?cè)谡{(diào)用時(shí),提供其它參數(shù),比如@decorator(a)。這樣,就為裝飾器的編寫和使用提供了更大的靈活性。
(在上面又套了一層函數(shù))
比如,我們可以在裝飾器中指定日志的等級(jí),因?yàn)椴煌瑯I(yè)務(wù)函數(shù)可能需要的日志級(jí)別是不一樣的。
def use_logging(level):
? ? def decorator(func):
? ? ? ? def wrapper(*args, **kwargs):
? ? ? ? ? ? if level == "warn":
? ? ? ? ? ? ? ? logging.warn("%s is running" % func.__name__)
? ? ? ? ? ? elif level == "info":
? ? ? ? ? ? ? ? logging.info("%s is running" % func.__name__)
? ? ? ? ? ? return func(*args)
? ? ? ? return wrapper
? ? return decorator
@use_logging(level="warn")
def foo(name='foo'):
? ? print("i am %s" % name)
foo()4.類裝飾器
沒錯(cuò),裝飾器不僅可以是函數(shù),還可以是類,相比函數(shù)裝飾器,類裝飾器具有靈活度大、高內(nèi)聚、封裝性等優(yōu)點(diǎn)。使用類裝飾器主要依靠類的__call__方法,當(dāng)使用 @ 形式將裝飾器附加到函數(shù)上時(shí),就會(huì)調(diào)用此方法。
class Foo(object):
? ? def __init__(self, func):
? ? ? ? self._func = func
? ? def __call__(self):
? ? ? ? print ('class decorator runing')
? ? ? ? self._func()
? ? ? ? print ('class decorator ending')
@Foo
def bar():
? ? print ('bar')
bar()
到此這篇關(guān)于python裝飾器代碼解析的文章就介紹到這了,更多相關(guān)python裝飾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)檢測(cè)文件的MD5值來查找重復(fù)文件案例
這篇文章主要介紹了Python實(shí)現(xiàn)檢測(cè)文件的MD5值來查找重復(fù)文件案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03
python多進(jìn)程使用函數(shù)封裝實(shí)例
這篇文章主要介紹了python多進(jìn)程使用函數(shù)封裝實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05
Python實(shí)戰(zhàn)之手勢(shì)識(shí)別控制電腦音量
這篇文章主要為大家詳細(xì)介紹了一個(gè)Python OpenCV的實(shí)戰(zhàn)小項(xiàng)目——手勢(shì)識(shí)別控制電腦音量,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-05-05
機(jī)器學(xué)習(xí)實(shí)戰(zhàn)之knn算法pandas
這篇文章主要為大家詳細(xì)介紹了機(jī)器學(xué)習(xí)實(shí)戰(zhàn)之knn算法pandas,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06
python中sort sorted reverse reversed函數(shù)的區(qū)別說明
這篇文章主要介紹了python中sort sorted reverse reversed函數(shù)的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05
Python開發(fā)常用五種循環(huán)方式的場(chǎng)景性能比較
Python是一門高級(jí)編程語言,其擁有多種循環(huán)方式,如for循環(huán)、while循環(huán)、do-while循環(huán)等。本文將逐個(gè)分析Python所有的循環(huán)執(zhí)行效率和適用場(chǎng)景,需要的可以參考一下2023-04-04
pycharm debug 斷點(diǎn)調(diào)試心得分享
這篇文章主要介紹了pycharm debug 斷點(diǎn)調(diào)試心得分享,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04
Django 使用Ajax進(jìn)行前后臺(tái)交互的示例講解
今天小編就為大家分享一篇Django 使用Ajax進(jìn)行前后臺(tái)交互的示例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-05-05
在PyCharm中實(shí)現(xiàn)關(guān)閉一個(gè)死循環(huán)程序的方法
今天小編就為大家分享一篇在PyCharm中實(shí)現(xiàn)關(guān)閉一個(gè)死循環(huán)程序的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-11-11

