分類(lèi)目錄:《系統(tǒng)學(xué)習(xí)Python》總目錄
函數(shù)裝飾器是如此有用,以至于Python2.X和Python3.X都擴(kuò)展了這一模式,允許裝飾器應(yīng)用于類(lèi)和函數(shù)。簡(jiǎn)而言之,類(lèi)裝飾器類(lèi)似于函數(shù)裝飾器,但它們是在一條class
語(yǔ)句的末尾運(yùn)行,并把一個(gè)類(lèi)名重新綁定到一個(gè)可調(diào)用對(duì)象。同樣,它們可以用來(lái)在類(lèi)一創(chuàng)建后就管理它們,或者當(dāng)隨后創(chuàng)建實(shí)例的時(shí)候插人一層包裝邏輯來(lái)管理實(shí)例。代碼結(jié)構(gòu)如下:
def decorator(aClass):
pass
@decorator
class C:
pass
被映射為下列等價(jià)代碼:
def decorator(aClass):
pass
class C:
pass
C = decorator(C)
類(lèi)裝飾器也可以擴(kuò)展類(lèi)自身,或者返回一個(gè)攔截了隨后的實(shí)例創(chuàng)建調(diào)用的代理對(duì)象。例如,在文章《系統(tǒng)學(xué)習(xí)Python——類(lèi)(class):靜態(tài)方法(staticmethod)和類(lèi)方法(classmethod)-[實(shí)例:用類(lèi)方法計(jì)數(shù)]》的示例中,我們可以使用這個(gè)鉤子來(lái)自動(dòng)地?cái)U(kuò)展需要實(shí)例計(jì)數(shù)器或任何其他所需數(shù)據(jù)的類(lèi):
def count(aClass):
aClass.numInstances = 0
return aClass
@count
class Spam:
pass
@count
class Sub(Spam):
pass
@count
class Other(Spam):
pass
事實(shí)上,正如所編寫(xiě)的那樣,該裝飾器可被用于類(lèi)或函數(shù),我們可以在初始化對(duì)象屬性之后,返回在這兩種上下文中定義的對(duì)象:
def count(aClass):
aClass.numInstances = 0
return aClass
@count
def spam():
pass
@count
class Sub:
pass
@count
class Other:
pass
print(spam.numInstances)
print(Other.numInstances)
輸出:
0
0
盡管這個(gè)裝飾器管理了一個(gè)函數(shù)或者類(lèi)本身,正如我們將在后面的文章看到的,類(lèi)裝飾器也可以通過(guò)攔截構(gòu)造函數(shù),并將新的實(shí)例對(duì)象包在一個(gè)代理(這個(gè)代理會(huì)部署屬性訪問(wèn)工具來(lái)攔截之后的屬性訪問(wèn)請(qǐng)求)中,來(lái)管理一個(gè)實(shí)例的全部接口,下面是這個(gè)模型的簡(jiǎn)單版本:
def decorator(cls):
class Proxy:
def __inir__(self, *args):
self.wrapper = cls(*args)
def __getattr__(self, name):
return getattr(self.wrapper, name)
return Proxy
@decorator
class C:
pass
X = C()
而元類(lèi)是一種類(lèi)似的基于類(lèi)的高級(jí)工具,其用途往往與類(lèi)裝飾器有所重合。它們提供了一種備選的模型,能把一個(gè)類(lèi)對(duì)象的創(chuàng)建路由到頂級(jí)type
類(lèi)的一個(gè)子類(lèi),在一條class
語(yǔ)句的最后。為了獲得對(duì)一個(gè)新的類(lèi)對(duì)象創(chuàng)建或初始化的控制,一個(gè)元類(lèi)通常重新定義type
類(lèi)的__new__
或者__init__
方法(這種做法通常用于攔截這兩種方法之一)。最終效果就像類(lèi)裝飾器一樣,定義了在類(lèi)創(chuàng)建時(shí)自動(dòng)運(yùn)行的代碼。在這里,這一步將類(lèi)名綁定到一個(gè)用戶(hù)定義元類(lèi)的調(diào)用結(jié)果。事實(shí)上,一個(gè)元類(lèi)完全可以不必是一個(gè)類(lèi)。我們將探討這種模糊了元類(lèi)與裝飾器之間區(qū)別的可能性,并且甚至比較這兩種工具在許多不同場(chǎng)景中的功能上的等價(jià)性。
類(lèi)裝飾器和元類(lèi)這兩種方案都可以用來(lái)擴(kuò)展一個(gè)類(lèi)或返回一個(gè)任意的對(duì)象來(lái)替代它一一一這是一種幾乎擁有無(wú)限的、基于類(lèi)的定制化可能性的協(xié)議。我們后面會(huì)看到,元類(lèi)也可以定義處理它們實(shí)例類(lèi)的方法,而不是這些實(shí)例類(lèi)的普通實(shí)例一一這是一種和類(lèi)方法很相似的技術(shù),而且可以用類(lèi)裝飾器代理中的方法和數(shù)據(jù)來(lái)模擬實(shí)現(xiàn),或者甚至是一個(gè)返回一個(gè)元類(lèi)實(shí)例的類(lèi)裝飾器。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-827106.html
參考文獻(xiàn):
[1] Mark Lutz. Python學(xué)習(xí)手冊(cè)[M]. 機(jī)械工業(yè)出版社, 2018.文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-827106.html
到了這里,關(guān)于系統(tǒng)學(xué)習(xí)Python——裝飾器:類(lèi)裝飾器-[初探類(lèi)裝飾器和元類(lèi)]的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!