您好,登錄后才能下訂單哦!
這篇文章主要為大家詳細介紹了函數裝飾器和類裝飾器的使用方法,文中示例代碼介紹的非常詳細,零基礎也能參考此文章,感興趣的小伙伴們可以參考一下。
裝飾器算是類里面比較難的內容之一,但是實際上它的思想并不復雜。簡單點說,就是在你原來內容的基礎上,在外面給你加點東西,實現類似裝飾的效果。但是它是怎么實現的呢?一般來說,都是通過攔截函數調用來實現的,比如:用裝飾器裝飾函數的時候,它攔截函數調用,裝飾類的時候,它攔截類實例的創建調用,即攔截類初始化__init__
函數。
知道這個原理以后,我們就可以來嘗試實現了。
首先來看通過函數裝飾器攔截類的創建過程,代碼如下:
instance = {}
def createInstance(cls, *args):
if cls not in instance:
instance[cls] = cls(*args)
return instance[cls]
def singleIns(cls):
def onCall(*args):
return createInstance(cls, *args)
return onCall
上面就是這個函數裝飾器singleIns的實現,它返回一個函數調用,當用它來裝飾一個類,創建類實例的時候,就會用onCall方法攔截類的__init__
方法。我們再來看一下它怎么使用的。
@singleIns
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "{} 的年齡是{}".format(self.name, self.age)
zhangsan = Person('zhangsan', 30)
lisi = Person('lisi', 29)
print(zhangsan)
print(lisi)
最終的輸出結果是:
zhangsan 的年齡是30
zhangsan 的年齡是30
為什么結果是一樣的?因為在創建實例的過程中,__init__
函數被onCall函數攔截,此時會進入到createInstance函數的流程中,會對這個類實例進行判斷,如果不存在這個類的實例,那么就初始化一個后返回,如果存在,直接返回第一個創建的類實例。因此最終只有一個類實例存在,就實現類單例類。
上面最開始的位置我們說了,函數裝飾器和類裝飾器都是攔截函數調用,在函數裝飾器實現類調用攔截的地方我們看到,它是通過函數裝飾器內部的函數來實現攔截的。如果是類裝飾器呢,它通過什么來攔截呢?
答案是call函數來攔截,我們來看一下類裝飾器的實現代碼:
class singleIns:
def __init__(self, cls):
self.cls = cls
self.ins = None
def __call__(self, *args):
if self.ins is None:
self.ins = self.cls(*args)
return self.ins
代碼和函數裝飾器相比,其實功能沒有太多變化,通過__call__
方法來接收被攔截類的初始化函數參數args,然后用args來初始化類實例。但是只在這個類還沒有實例的情況下進行初始化,否則直接返會初始化好的類。
我們來看一下應用的代碼:
@singleIns
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "{} 的年齡是{}".format(self.name, self.age)
zhangsan = Person('zhangsan', 30)
lisi = Person('lisi', 29)
print(zhangsan)
print(lisi)
最終的結果和上面函數裝飾器的一樣,如下所示:
zhangsan 的年齡是30
zhangsan 的年齡是30
看完上述內容,你們對函數裝飾器和類裝飾器的使用方法大概了解了嗎?如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。