如何真正的了解python裝飾器
合理使用裝飾器可以簡化開發(fā),并且使得代碼更加清晰。下面我們分別介紹兩種裝飾器,不帶參數(shù)的裝飾器和帶參數(shù)的裝飾器。
一、不帶參數(shù)的裝飾器
我們用一個實際的例子來引入裝飾器的概念,比如我們現(xiàn)在有一個方法A(),然后我們需要在方法A()執(zhí)行之前在終端打印"function is running",這時候我們可以在方法A()的開始部分加上下面的代碼:
print("function is running")
但是如果我們不想修改方法A()的代碼,也可以重新寫一個方法decorator(),然后把A()作為入?yún)?,代碼如下:
def decorator(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
print("Method is running")
return fun()
return wrapper
python中的方法可以作為參數(shù)傳入另一個方法,所以當(dāng)我們執(zhí)行decorator(A)的時候,返回的是一個方法,這個方法的本質(zhì)是先執(zhí)行print語句,然后再執(zhí)行A()。
但是這樣我們的調(diào)用代碼就需要進行修改,也就是說之前調(diào)用方法A(),現(xiàn)在的寫法是調(diào)用decorator(A)(),為了不影響調(diào)用的代碼,我們使用python的語法糖改造方法A()的代碼。
@decorator def A(): # do something
實際上只是在A()的前面加上一行@decorator,這樣在我們的調(diào)用代碼就不需要改變了。
裝飾器中的@functools.wraps(fun)是為了保證返回的方法__name__屬性和入?yún)⒎椒╢un的__name__屬性相同。
二、帶入?yún)⒌难b飾器
在上面不帶參數(shù)的裝飾器中,我們實現(xiàn)了在執(zhí)行方法A()之前打印一行固定的字符串,如果我們想要打印不同的字符串就需要用帶參數(shù)的裝飾器。實際上就是在不帶參數(shù)的裝飾器上再封裝一層即可,代碼如下:
def decorator_par(name):
def decorator(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
print("Method {} is running".format(name))
return fun()
return wrapper
return decorator
這樣我們就可以在使用裝飾器的時候設(shè)置參數(shù)name,實現(xiàn)打印不同的信息。完整的代碼如下:
import functools
def decorator_par(name):
def decorator(fun):
@functools.wraps(fun)
def wrapper(*args, **kwargs):
print("Method {} is running".format(name))
return fun()
return wrapper
return decorator
@decorator_par("A")
def A():
print("I am A")
@decorator_par("B")
def B():
print("I am B")
A()
B()
執(zhí)行輸出為:
Method A is running I am A Method B is running I am B
可以看到我們在不改變方法調(diào)用代碼的情況下,實現(xiàn)了在該方法之前打印特定的信息。
以上就是裝飾器的兩種實現(xiàn)示例,實際開發(fā)中也可以將多個裝飾器進行嵌套,可以實現(xiàn)更加復(fù)雜的需求。
內(nèi)容擴展:
python函數(shù)式編程之裝飾器
1.開放封閉原則
簡單來說,就是對擴展開放,對修改封閉。
在面向?qū)ο蟮木幊谭绞街?,?jīng)常會定義各種函數(shù)。一個函數(shù)的使用分為定義階段和使用階段,一個函數(shù)定義完成以后,可能會在很多位置被調(diào)用。這意味著如果函數(shù)的定義階段代碼被修改,受到影響的地方就會有很多,此時很容易因為一個小地方的修改而影響整套系統(tǒng)的崩潰,所以對于現(xiàn)代程序開發(fā)行業(yè)來說,一套系統(tǒng)一旦上線,系統(tǒng)的源代碼就一定不能夠再改動了。然而一套系統(tǒng)上線以后,隨著用戶數(shù)量的不斷增加,一定會為一套系統(tǒng)擴展添加新的功能。
此時,又不能修改原有系統(tǒng)的源代碼,又要為原有系統(tǒng)開發(fā)增加新功能,這就是程序開發(fā)行業(yè)的開放封閉原則,這時就要用到裝飾器了。
2.什么是裝飾器
裝飾器,顧名思義,就是裝飾,修飾別的對象的一種工具。
所以裝飾器可以是任意可調(diào)用的對象,被裝飾的對象也可以是任意可調(diào)用對象。
3.裝飾器的作用
在不修改被裝飾對象的源代碼以及調(diào)用方式的前提下為被裝飾對象添加新功能。
以上就是如何真正的了解python裝飾器的詳細(xì)內(nèi)容,更多關(guān)于你真的了解python裝飾器么的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Pytorch根據(jù)layers的name凍結(jié)訓(xùn)練方式
今天小編就為大家分享一篇Pytorch根據(jù)layers的name凍結(jié)訓(xùn)練方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01
Object arrays cannot be loaded when
這篇文章主要介紹了Object arrays cannot be loaded when allow_pickle=False,本文給大家分享問題解決思路,需要的朋友可以參考下2022-11-11
python裝飾器-限制函數(shù)調(diào)用次數(shù)的方法(10s調(diào)用一次)
下面小編就為大家分享一篇python裝飾器-限制函數(shù)調(diào)用次數(shù)的方法(10s調(diào)用一次),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04
django orm 通過related_name反向查詢的方法
今天小編就為大家分享一篇django orm 通過related_name反向查詢的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
Python實現(xiàn)讀取Excel文件并復(fù)制指定的數(shù)據(jù)行
這篇文章主要介紹了如何基于Python語言,讀取Excel表格文件數(shù)據(jù),并基于其中某一列數(shù)據(jù)的值,將這一數(shù)據(jù)處于指定范圍的那一行加以復(fù)制,感興趣的可以了解一下2023-07-07

