溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Python中怎么創(chuàng)建一個(gè)元類(lèi)

發(fā)布時(shí)間:2021-07-10 14:32:27 來(lái)源:億速云 閱讀:154 作者:Leah 欄目:編程語(yǔ)言

Python中怎么創(chuàng)建一個(gè)元類(lèi),很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。


    什么是Python元類(lèi)?

    Python元類(lèi)是與Python的面向?qū)ο缶幊谈拍钕嚓P(guān)的高級(jí)功能之一。它確定類(lèi)的行為,并進(jìn)一步幫助其修改。

    Python中怎么創(chuàng)建一個(gè)元類(lèi)

    用Python創(chuàng)建的每個(gè)類(lèi)都有一個(gè)基礎(chǔ)的Metaclass。因此,在創(chuàng)建類(lèi)時(shí),您將間接使用元類(lèi)。它隱式發(fā)生,您無(wú)需指定任何內(nèi)容。

    與元編程相關(guān)聯(lián)的元類(lèi)決定了程序?qū)ζ渥陨磉M(jìn)行操作的能力。 學(xué)習(xí)元類(lèi)可能看起來(lái)很復(fù)雜,但是讓我們先從一些類(lèi)和對(duì)象的概念入手,以便于理解。

    Python中的類(lèi)和對(duì)象

    類(lèi)是一個(gè)藍(lán)圖,是具有對(duì)象的邏輯實(shí)體。 一個(gè)簡(jiǎn)單的類(lèi)在聲明時(shí)沒(méi)有分配任何內(nèi)存,它是在創(chuàng)建一個(gè)類(lèi)的實(shí)例時(shí)發(fā)生的。

    通過(guò)創(chuàng)建的對(duì)象,可以訪問(wèn)該類(lèi)。該類(lèi)僅用作模板。對(duì)象的屬性本質(zhì)上意味著我們可以在運(yùn)行時(shí)與它進(jìn)行交互,傳遞諸如變量之類(lèi)的參數(shù),進(jìn)行存儲(chǔ),修改,也可以與它進(jìn)行交互。

    可以使用__class__屬性檢查對(duì)象的類(lèi)。讓我們看一個(gè)簡(jiǎn)單的例子:

    class Demo: 
           pass       
    #This is a class named demo
     test=Demo()
    print(test.__class__)  #shows class of obj
    print(type(test))  #alternate method

    Output: <class '__main__.Demo'>

    Python大量處理類(lèi)和對(duì)象的概念,并允許輕松,順利地進(jìn)行應(yīng)用程序開(kāi)發(fā)。但是,什么使Python與Java和C這樣的語(yǔ)言不同呢?Python中的所有內(nèi)容都可以定義為具有屬性和方法的對(duì)象。 主題演講是Python中的類(lèi)不過(guò)是更大類(lèi)的另一個(gè)對(duì)象。

    Python中怎么創(chuàng)建一個(gè)元類(lèi)

    類(lèi)為對(duì)象定義規(guī)則。同樣,元類(lèi)負(fù)責(zé)為類(lèi)分配行為。我們已經(jīng)知道,類(lèi)是對(duì)象,就像每個(gè)對(duì)象都有一個(gè)實(shí)例一樣,類(lèi)是元類(lèi)的實(shí)例。

    但是也有像Ruby和Objective-C這樣的語(yǔ)言也支持元類(lèi)。那么,是什么使Python Metaclass更好,為什么還要學(xué)習(xí)它呢?答案是Python中的動(dòng)態(tài)類(lèi)。讓我們仔細(xì)看看。

    Python中的動(dòng)態(tài)類(lèi)

    Python是一種動(dòng)態(tài)編程語(yǔ)言,并允許在運(yùn)行時(shí)創(chuàng)建類(lèi)。與C ++等其他語(yǔ)言不同,后者僅允許在編譯時(shí)創(chuàng)建類(lèi)。在靈活性方面,Python優(yōu)于其他靜態(tài)類(lèi)型的語(yǔ)言。

    動(dòng)態(tài)和靜態(tài)類(lèi)型語(yǔ)言之間的差異并不大, 但是在Python中,它由于提供元編程而變得更加有用。

    但是,如果我告訴您還有另一個(gè)關(guān)鍵功能將Python與其他編程語(yǔ)言區(qū)分開(kāi)呢?

    諸如Java或C ++之類(lèi)的語(yǔ)言具有float,char,int等數(shù)據(jù)類(lèi)型,而Python將每個(gè)變量視為對(duì)象。每個(gè)對(duì)象都屬于一個(gè)類(lèi),例如int類(lèi)或str類(lèi)。您可以使用稱(chēng)為type()的內(nèi)置函數(shù)來(lái)簡(jiǎn)單地檢查任何變量的類(lèi)

    number = 10993
    print("Type associated is:", type(number))
    name = "Aishwarya"
    print("Type associated is:", type(name))

    Output:

    Type associated is: <class 'int'>

    Type associated is: <class 'str'>

    現(xiàn)在,您了解了Python中的所有內(nèi)容都有與之關(guān)聯(lián)的類(lèi)型。在下一個(gè)主題中,我們將嘗試了解元類(lèi)實(shí)際上是如何工作的。

    Python元類(lèi)如何工作?

    每當(dāng)創(chuàng)建一個(gè)類(lèi)時(shí),都會(huì)調(diào)用默認(rèn)的Metaclass類(lèi)型。 元類(lèi)包含名稱(chēng),基類(lèi)集以及與該類(lèi)關(guān)聯(lián)的屬性等信息。因此,在實(shí)例化一個(gè)類(lèi)時(shí),將調(diào)用帶有這些參數(shù)的類(lèi)。可以通過(guò)兩種方法創(chuàng)建元類(lèi):

    1. 類(lèi)型類(lèi)

    2. 自定義元類(lèi)

    讓我們繼續(xù)輸入class以及如何創(chuàng)建class。

    類(lèi)型類(lèi)

    Python有一個(gè)稱(chēng)為type的內(nèi)置元類(lèi)。與Java或C不同,那里有主要的數(shù)據(jù)類(lèi)型。Python中的每個(gè)變量或?qū)ο蠖加幸粋€(gè)與之關(guān)聯(lián)的類(lèi)。Python使用幕后的Type類(lèi)創(chuàng)建所有類(lèi)。在上一個(gè)主題中,我們看到了如何使用type()檢查對(duì)象的類(lèi)。讓我們舉一個(gè)例子,說(shuō)明如何通過(guò)創(chuàng)建一個(gè)簡(jiǎn)單的類(lèi)來(lái)定義新類(lèi)型。

    class Edureka():
    obj = Edureka()
     
    print(type(obj))

    Output: <class '__main__.Edureka'>

    print(type(Edureka))

    Output: <class 'type'>

    在上面的代碼中,我們有一個(gè)名為Edureka的類(lèi),以及一個(gè)關(guān)聯(lián)的對(duì)象。我們通過(guò)簡(jiǎn)單地在該類(lèi)型之后創(chuàng)建一個(gè)名為自身的類(lèi),創(chuàng)建了一個(gè)名為Edureka的新類(lèi)型。在第二個(gè)代碼中,當(dāng)我們檢查Edureka類(lèi)的類(lèi)型時(shí),其結(jié)果為“類(lèi)型”。

    因此,除非另有定義,否則元類(lèi)使用類(lèi)型類(lèi)來(lái)創(chuàng)建所有其他類(lèi)。我們可以通過(guò)兩種方法訪問(wèn)Type類(lèi):

    Python中怎么創(chuàng)建一個(gè)元類(lèi)

    當(dāng)我們通過(guò)類(lèi)型類(lèi)傳遞參數(shù)時(shí),它使用以下語(yǔ)法。

    type(__name__, __base__, attributes)
    • 名稱(chēng)是一個(gè)字符串,并帶有類(lèi)名

    • 該基礎(chǔ)是一個(gè)元組,可幫助創(chuàng)建子類(lèi)

    • 屬性是字典,并分配鍵值對(duì)

    由于Python中的類(lèi)的行為與對(duì)象相似,因此可以用相同的方式更改其行為。我們可以在類(lèi)內(nèi)添加或刪除方法,類(lèi)似于對(duì)對(duì)象的處理方式。

    現(xiàn)在您已經(jīng)知道Metaclass在Python中創(chuàng)建了所有其他類(lèi),并使用類(lèi)型class定義了它們的行為。但是,您一定想知道,我們還有其他方法可以創(chuàng)建元類(lèi)嗎?因此,讓我們看看如何創(chuàng)建一個(gè)自定義的元類(lèi)。

    Python中的自定義元類(lèi)

    現(xiàn)在我們知道并理解類(lèi)型類(lèi)如何工作。現(xiàn)在該學(xué)習(xí)如何創(chuàng)建自定義元類(lèi)了。我們可以通過(guò)執(zhí)行動(dòng)作或代碼注入來(lái)修改類(lèi)的工作。為此,我們可以在創(chuàng)建類(lèi)定義時(shí)將Metaclass作為關(guān)鍵字傳遞。另外,我們可以通過(guò)簡(jiǎn)單地繼承通過(guò)此Metaclass關(guān)鍵字實(shí)例化的類(lèi)來(lái)實(shí)現(xiàn)此目的。

    在創(chuàng)建新類(lèi)時(shí),Python查找__metaclass__ 關(guān)鍵字。以防萬(wàn)一,如果不存在。它遵循類(lèi)型類(lèi)層次結(jié)構(gòu)。

    Python中怎么創(chuàng)建一個(gè)元類(lèi)

    Python在命名空間中執(zhí)行所有字典后,將調(diào)用類(lèi)型對(duì)象,后者創(chuàng)建類(lèi)的對(duì)象。我們可以使用兩種方法來(lái)創(chuàng)建自定義元類(lèi)。

    Python中怎么創(chuàng)建一個(gè)元類(lèi)

    class EduFirst(type):
    def __new__(cls, name, base_cls, dict):
    pass
    class EduSecond(type):
    def __init__(self, name, base_cls, dict):
    pass

    讓我詳細(xì)解釋這兩種方法:

    1. __new __(): 當(dāng)用戶(hù)要在類(lèi)創(chuàng)建之前定義元組字典時(shí)使用。它返回一個(gè)類(lèi)的實(shí)例,并且很容易覆蓋/管理對(duì)象流。

    2. __init __():在創(chuàng)建對(duì)象并對(duì)其進(jìn)行初始化之后調(diào)用它。

    Python中的__call__是什么?

    在正式的Python文檔中,__call__方法可用于定義自定義元類(lèi)。同樣,當(dāng)調(diào)用類(lèi)定義自定義行為時(shí),我們可以覆蓋__prepare__之類(lèi)的其他方法。

    就像類(lèi)如何像創(chuàng)建對(duì)象的模板一樣,元類(lèi)也像類(lèi)創(chuàng)建模板一樣。因此,元類(lèi)也稱(chēng)為類(lèi)工廠。

    請(qǐng)參見(jiàn)下一個(gè)示例:

    class Meta(type):
    def __init__(cls, name, base, dct):
    cls.attribute = 200
    class Test(metaclass = Meta):
    pass
    Test.attribute

    Output: 200

    元類(lèi)允許自定義類(lèi)。還有多種其他有效且簡(jiǎn)單得多的方法可以通過(guò)這些方法實(shí)現(xiàn)相同的輸出。這樣的例子之一就是使用裝飾器。

    裝飾器vs元類(lèi)

    Decorator是Python的一項(xiàng)流行功能,它允許您向代碼中添加更多功能。裝飾器是可調(diào)用的對(duì)象,可幫助修改現(xiàn)有的類(lèi)甚至函數(shù)。在編譯期間,部分代碼將調(diào)用并修改另一部分。此過(guò)程也稱(chēng)為元編程。

    Python中怎么創(chuàng)建一個(gè)元類(lèi)

    def decorator(cls):
    class NewClass(cls):
    attribute = 200
     return NewClass
    @decorator
    Class Test1:
     pass
    @decorator
     
    Class Test2:
     pass
    Test1.attribute
     
    Test2.attribute

    看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI