摘要:通過本文,將深入討論Python元類,其屬性,如何以及何時在Python中使用元類。
Python元類設定類的行為和規則。元類有助於修改類的例項,並且相當複雜,是Python程式設計的高階功能之一。通過本文,將深入討論Python元類,其屬性,如何以及何時在Python中使用元類。本文介紹以下概念:
- 什麼是Python元類?
- Python中的類和物件
- Python中的動態類
- Python元類如何工作?
- 型別類
- Python中的自定義元類
- 裝飾器vs元類
什麼是Python元類?
Python元類是與Python的物件導向程式設計概念相關的高階功能之一。它確定類的行為,並進一步幫助其修改。
用Python建立的每個類都有一個基礎的Metaclass。因此,在建立類時,您將間接使用元類。它隱式發生,您無需指定任何內容。
與超程式設計相關聯的元類決定了程式對其自身進行操作的能力。 學習元類可能看起來很複雜,但是讓我們先從一些類和物件的概念入手,以便於理解。
Python中的類和物件
類是一個藍圖,是具有物件的邏輯實體。 一個簡單的類在宣告時沒有分配任何記憶體,它是在建立一個類的例項時發生的。
通過建立的物件,可以訪問該類。該類僅用作模板。物件的屬性本質上意味著我們可以在執行時與它進行互動,傳遞諸如變數之類的引數,進行儲存,修改,也可以與它進行互動。
可以使用__class__屬性檢查物件的類。讓我們看一個簡單的例子:
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大量處理類和物件的概念,並允許輕鬆,順利地進行應用程式開發。但是,什麼使Python與Java和C這樣的語言不同呢?Python中的所有內容都可以定義為具有屬性和方法的物件。 主題演講是Python中的類不過是更大類的另一個物件。
類為物件定義規則。同樣,元類負責為類分配行為。我們已經知道,類是物件,就像每個物件都有一個例項一樣,類是元類的例項。
但是也有像Ruby和Objective-C這樣的語言也支援元類。那麼,是什麼使Python Metaclass更好,為什麼還要學習它呢?答案是Python中的動態類。讓我們仔細看看。
Python中的動態類
Python是一種動態程式語言,並允許在執行時建立類。與C ++等其他語言不同,後者僅允許在編譯時建立類。在靈活性方面,Python優於其他靜態型別的語言。
動態和靜態型別語言之間的差異並不大, 但是在Python中,它由於提供超程式設計而變得更加有用。
但是,如果我告訴您還有另一個關鍵功能將Python與其他程式語言區分開呢?
諸如Java或C ++之類的語言具有float,char,int等資料型別,而Python將每個變數視為物件。每個物件都屬於一個類,例如int類或str類。您可以使用稱為type()的內建函式來簡單地檢查任何變數的類。
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'>
現在,您瞭解了Python中的所有內容都有與之關聯的型別。在下一個主題中,我們將嘗試瞭解元類實際上是如何工作的。
Python元類如何工作?
每當建立一個類時,都會呼叫預設的Metaclass型別。 元類包含名稱,基類集以及與該類關聯的屬性等資訊。因此,在例項化一個類時,將呼叫帶有這些引數的類。可以通過兩種方法建立元類:
- 型別類
- 自定義元類
讓我們繼續輸入class以及如何建立class。
型別類
Python有一個稱為type的內建元類。與Java或C不同,那裡有主要的資料型別。Python中的每個變數或物件都有一個與之關聯的類。Python使用幕後的Type類建立所有類。在上一個主題中,我們看到了如何使用type()檢查物件的類。讓我們舉一個例子,說明如何通過建立一個簡單的類來定義新型別。
class Edureka(): obj = Edureka() print(type(obj))
Output: <class '__main__.Edureka'>
print(type(Edureka))
Output: <class 'type'>
在上面的程式碼中,我們有一個名為Edureka的類,以及一個關聯的物件。我們通過簡單地在該型別之後建立一個名為自身的類,建立了一個名為Edureka的新型別。在第二個程式碼中,當我們檢查Edureka類的型別時,其結果為“型別”。
因此,除非另有定義,否則元類使用型別類來建立所有其他類。我們可以通過兩種方法訪問Type類:
當我們通過型別類傳遞引數時,它使用以下語法。
type(__name__, __base__, attributes)
- 名稱是一個字串,並帶有類名
- 該基礎是一個元組,可幫助建立子類
- 屬性是字典,並分配鍵值對
由於Python中的類的行為與物件相似,因此可以用相同的方式更改其行為。我們可以在類內新增或刪除方法,類似於對物件的處理方式。
現在您已經知道Metaclass在Python中建立了所有其他類,並使用型別class定義了它們的行為。但是,您一定想知道,我們還有其他方法可以建立元類嗎?因此,讓我們看看如何建立一個自定義的元類。
Python中的自定義元類
現在我們知道並理解型別類如何工作。現在該學習如何建立自定義元類了。我們可以通過執行動作或程式碼注入來修改類的工作。為此,我們可以在建立類定義時將Metaclass作為關鍵字傳遞。另外,我們可以通過簡單地繼承通過此Metaclass關鍵字例項化的類來實現此目的。
在建立新類時,Python查詢__metaclass__ 關鍵字。以防萬一,如果不存在。它遵循型別類層次結構。
Python在名稱空間中執行所有字典後,將呼叫型別物件,後者建立類的物件。我們可以使用兩種方法來建立自定義元類。
class EduFirst(type): def __new__(cls, name, base_cls, dict): pass class EduSecond(type): def __init__(self, name, base_cls, dict): pass
讓我詳細解釋這兩種方法:
- __new __(): 當使用者要在類建立之前定義元組字典時使用。它返回一個類的例項,並且很容易覆蓋/管理物件流。
- __init __():在建立物件並對其進行初始化之後呼叫它。
Python中的__call__是什麼?
在正式的Python文件中,__call__方法可用於定義自定義元類。同樣,當呼叫類定義自定義行為時,我們可以覆蓋__prepare__之類的其他方法。
就像類如何像建立物件的模板一樣,元類也像類建立模板一樣。因此,元類也稱為類工廠。
請參見下一個示例:
class Meta(type): def __init__(cls, name, base, dct): cls.attribute = 200 class Test(metaclass = Meta): pass Test.attribute
Output: 200
元類允許自定義類。還有多種其他有效且簡單得多的方法可以通過這些方法實現相同的輸出。這樣的例子之一就是使用裝飾器。
裝飾器vs元類
Decorator是Python的一項流行功能,它允許您向程式碼中新增更多功能。裝飾器是可呼叫的物件,可幫助修改現有的類甚至函式。在編譯期間,部分程式碼將呼叫並修改另一部分。此過程也稱為超程式設計。
def decorator(cls): class NewClass(cls): attribute = 200 return NewClass @decorator Class Test1: pass @decorator Class Test2: pass Test1.attribute Test2.attribute
Output: 200
Python中的Decorator是一個非常有用且功能強大的工具,可幫助您更改函式的行為,而無需實際更改任何程式碼。 當您要在除錯時修改程式的一部分而不是重寫函式或更改整個程式時,這非常方便。取而代之的是,您只需編寫一個單行裝飾器,其餘的就由它來處理。
本文分享自華為雲社群《如何建立您的第一個Python元類?》,原文作者:Yuchuan。