函數(shù)裝飾器和類裝飾器的使用方法

這篇文章主要為大家詳細(xì)介紹了函數(shù)裝飾器和類裝飾器的使用方法,文中示例代碼介紹的非常詳細(xì),零基礎(chǔ)也能參考此文章,感興趣的小伙伴們可以參考一下。

創(chuàng)新新互聯(lián),憑借10多年的網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)經(jīng)驗(yàn),本著真心·誠(chéng)心服務(wù)的企業(yè)理念服務(wù)于成都中小企業(yè)設(shè)計(jì)網(wǎng)站有1000多家案例。做網(wǎng)站建設(shè),選創(chuàng)新互聯(lián)

函數(shù)裝飾器實(shí)現(xiàn)

裝飾器算是類里面比較難的內(nèi)容之一,但是實(shí)際上它的思想并不復(fù)雜。簡(jiǎn)單點(diǎn)說(shuō),就是在你原來(lái)內(nèi)容的基礎(chǔ)上,在外面給你加點(diǎn)東西,實(shí)現(xiàn)類似裝飾的效果。但是它是怎么實(shí)現(xiàn)的呢?一般來(lái)說(shuō),都是通過(guò)攔截函數(shù)調(diào)用來(lái)實(shí)現(xiàn)的,比如:用裝飾器裝飾函數(shù)的時(shí)候,它攔截函數(shù)調(diào)用,裝飾類的時(shí)候,它攔截類實(shí)例的創(chuàng)建調(diào)用,即攔截類初始化__init__函數(shù)。
知道這個(gè)原理以后,我們就可以來(lái)嘗試實(shí)現(xiàn)了。

首先來(lái)看通過(guò)函數(shù)裝飾器攔截類的創(chuàng)建過(guò)程,代碼如下:

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

上面就是這個(gè)函數(shù)裝飾器singleIns的實(shí)現(xiàn),它返回一個(gè)函數(shù)調(diào)用,當(dāng)用它來(lái)裝飾一個(gè)類,創(chuàng)建類實(shí)例的時(shí)候,就會(huì)用onCall方法攔截類的__init__方法。我們?cè)賮?lái)看一下它怎么使用的。

@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)

最終的輸出結(jié)果是:

zhangsan 的年齡是30
zhangsan 的年齡是30

為什么結(jié)果是一樣的?因?yàn)樵趧?chuàng)建實(shí)例的過(guò)程中,__init__函數(shù)被onCall函數(shù)攔截,此時(shí)會(huì)進(jìn)入到createInstance函數(shù)的流程中,會(huì)對(duì)這個(gè)類實(shí)例進(jìn)行判斷,如果不存在這個(gè)類的實(shí)例,那么就初始化一個(gè)后返回,如果存在,直接返回第一個(gè)創(chuàng)建的類實(shí)例。因此最終只有一個(gè)類實(shí)例存在,就實(shí)現(xiàn)類單例類。

類裝飾器實(shí)現(xiàn)

上面最開(kāi)始的位置我們說(shuō)了,函數(shù)裝飾器和類裝飾器都是攔截函數(shù)調(diào)用,在函數(shù)裝飾器實(shí)現(xiàn)類調(diào)用攔截的地方我們看到,它是通過(guò)函數(shù)裝飾器內(nèi)部的函數(shù)來(lái)實(shí)現(xiàn)攔截的。如果是類裝飾器呢,它通過(guò)什么來(lái)攔截呢?
答案是call函數(shù)來(lái)攔截,我們來(lái)看一下類裝飾器的實(shí)現(xiàn)代碼:

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

代碼和函數(shù)裝飾器相比,其實(shí)功能沒(méi)有太多變化,通過(guò)__call__方法來(lái)接收被攔截類的初始化函數(shù)參數(shù)args,然后用args來(lái)初始化類實(shí)例。但是只在這個(gè)類還沒(méi)有實(shí)例的情況下進(jìn)行初始化,否則直接返會(huì)初始化好的類。
我們來(lái)看一下應(yīng)用的代碼:

@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)

最終的結(jié)果和上面函數(shù)裝飾器的一樣,如下所示:

zhangsan 的年齡是30
zhangsan 的年齡是30

看完上述內(nèi)容,你們對(duì)函數(shù)裝飾器和類裝飾器的使用方法大概了解了嗎?如果想了解更多相關(guān)文章內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

網(wǎng)頁(yè)名稱:函數(shù)裝飾器和類裝飾器的使用方法
文章地址:http://muchs.cn/article46/jepheg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、移動(dòng)網(wǎng)站建設(shè)、ChatGPT網(wǎng)站維護(hù)、自適應(yīng)網(wǎng)站、網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名