Python中裝飾器使用方法整理
1 裝飾器初階
裝飾器是一種設(shè)計模式,起到裝飾的作用。就是在不修改函數(shù)代碼的情況下,給函數(shù)增加一些功能。
1.1 沒有使用裝飾器的例子
現(xiàn)有一個返回字符串的函數(shù),在不修改該函數(shù)的情況下,將返回的字符串轉(zhuǎn)換為大寫字符串。
def uppercase_decorator(func): # 定義一個函數(shù),其參數(shù)func是函數(shù)類型參數(shù) def inner(): # 嵌套函數(shù)inner s = func() # 調(diào)用func()函數(shù)并將返回值賦值給s變量 make_uppercase = s.upper() # 將字符串轉(zhuǎn)換為大寫并賦值給make_uppercase return make_uppercase # 結(jié)束嵌套函數(shù)func()調(diào)用,返回轉(zhuǎn)換之后的字符串 return inner # 結(jié)束函數(shù)uppercase_decorator()調(diào)用, 返回嵌套函數(shù)inner def say_hello(): return 'hello world.' if __name__=="__main__": say_hello2 = uppercase_decorator(say_hello) # 調(diào)用uppercase_decorator()函數(shù),實參是say_hello()函數(shù),返回值say_hello2變量也是一個函數(shù) print(say_hello2()) # 調(diào)用say_hello2函數(shù)
1.2 使用裝飾器
Python提供了裝飾器注釋功能,裝飾器本質(zhì)上是一個函數(shù)。 上述代碼使用裝飾器修改如下:
def uppercase_decorator(func): def inner(): s = func() make_uppercase = s.upper() return make_uppercase return inner @uppercase_decorator # 使用@uppercase_decorator裝飾器聲明say_hello1()函數(shù) def say_hello1(): return "zhang cheng." if __name__=="__main__": print(say_hello1()) # 使用裝飾器不需要顯式調(diào)用uppercase_decorator()函數(shù),直接調(diào)用say_hello1()函數(shù)即可。
1.3 同時使用多個裝飾器
一個函數(shù)可以有多個裝飾器聲明。
def uppercase_decorator(func): # 將字符串轉(zhuǎn)換成大寫 def inner(): s = func() make_uppercase = s.upper() return make_uppercase return inner def backet_decorator(func): # 給字符串添加括號 def inner(): s = func() make_bracket = '(' + s + ')' return make_bracket return inner @backet_decorator @uppercase_decorator def say_hello(): return 'hello world.' if __name__=="__main__": print(say_hello())
1.4 給裝飾器傳遞參數(shù)
裝飾器本質(zhì)上是函數(shù),因此可以給裝飾器傳遞參數(shù)。
def calc(func): # 定義裝飾器函數(shù)calc(func),其參數(shù)還是一個函數(shù) def wrapper(arg1): # 定義嵌套函數(shù)wrapper(arg1),這個函數(shù)參數(shù)列表與裝飾器要注釋的函數(shù)參數(shù)列表一致 return func(arg1) return wrapper @calc def square(n): return n * n @calc def abs(n): return n if n > 0 else -n if __name__=="__main__": print(f"3's square is {square(3)}") print(f"-30's absulate is {abs(-30)}")
2 裝飾器高階
2.1 wraps(func)使用
需要使用包:
from functools import wraps
作用:不改變使用裝飾器的原有函數(shù)func的結(jié)構(gòu)。(比如入?yún)⒏袷降?,__name__, __doc__ );
因為一個原函數(shù)使用了裝飾器之后,那么它就自動默認(rèn)指向了裝飾器函數(shù)的內(nèi)存地址。 沒有使用wraps裝飾器,代碼如下:
def add_decorator(func): def inner(): """ This is a decorator. :return: """ func() pass return inner @add_decorator def add(): """ This is a add. :return: """ pass if __name__=="__main__": print(add.__name__) print(add.__doc__)
運行結(jié)果:
inner
This is a decorator.
:return:
結(jié)果分析:未加上@wraps()裝飾器,結(jié)果得知add函數(shù)指向的是引用的裝飾器函數(shù)inner.
使用wraps裝飾器,代碼如下:
from functools import wraps def add_decorator(func): @wraps(func) def inner(): """ This is a decorator. :return: """ func() pass return inner @add_decorator def add(): """ This is a add. :return: """ pass if __name__=="__main__": print(add.__name__) print(add.__doc__)
運行結(jié)果如下:
add
This is a add.
:return:
結(jié)果分析:加上@wraps()裝飾器,結(jié)果得知add函數(shù)的結(jié)構(gòu)保持不變.
提示:__name__輸出函數(shù)名; __doc__輸出對應(yīng)函數(shù)內(nèi)的注釋信息。
2.2 多層嵌套使用
from functools import wraps def add_deco(z): def add_decorator(func): @wraps(func) def inner(x, y): return z + func(x, y) return inner return add_decorator @add_deco(z=10) def add(x, y): return x + y if __name__=="__main__": print(add(5, 10))
運行結(jié)果如下:
25
到此這篇關(guān)于Python中裝飾器使用方法整理的文章就介紹到這了,更多相關(guān)Python中的裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python正則表達式re.compile()和re.findall()詳解
re?模塊提供了不少有用的函數(shù),用以匹配字符串,下面這篇文章主要給大家介紹了關(guān)于Python正則表達式re.compile()和re.findall()的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07python 監(jiān)聽salt job狀態(tài),并任務(wù)數(shù)據(jù)推送到redis中的方法
今天小編就為大家分享一篇python 監(jiān)聽salt job狀態(tài),并任務(wù)數(shù)據(jù)推送到redis中的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01Python Serial串口基本操作(收發(fā)數(shù)據(jù))
這篇文章主要介紹了Python Serial串口基本操作(收發(fā)數(shù)據(jù)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11PyCharm遠(yuǎn)程調(diào)試代碼配置以及運行參數(shù)設(shè)置方式
這篇文章主要介紹了PyCharm遠(yuǎn)程調(diào)試代碼配置以及運行參數(shù)設(shè)置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01