天天看點

Python進階丨如何建立你的第一個Python元類?

摘要:通過本文,将深入讨論Python元類,其屬性,如何以及何時在Python中使用元類。

Python元類設定類的行為和規則。元類有助于修改類的執行個體,并且相當複雜,是Python程式設計的進階功能之一。通過本文,将深入讨論Python元類,其屬性,如何以及何時在Python中使用元類。本文介紹以下概念:

    • 什麼是Python元類?
    • Python中的類和對象
    • Python中的動态類
    • Python元類如何工作?
      • 類型類
      • Python中的自定義元類
    • 裝飾器vs元類

Python元類是與Python的面向對象程式設計概念相關的進階功能之一。它确定類的行為,并進一步幫助其修改。

Python進階丨如何建立你的第一個Python元類?

用Python建立的每個類都有一個基礎的Metaclass。是以,在建立類時,您将間接使用元類。它隐式發生,您無需指定任何内容。

與元程式設計相關聯的元類決定了程式對其自身進行操作的能力。 學習元類可能看起來很複雜,但是讓我們先從一些類和對象的概念入手,以便于了解。

類是一個藍圖,是具有對象的邏輯實體。 一個簡單的類在聲明時沒有配置設定任何記憶體,它是在建立一個類的執行個體時發生的。

通過建立的對象,可以通路該類。該類僅用作模闆。對象的屬性本質上意味着我們可以在運作時與它進行互動,傳遞諸如變量之類的參數,進行存儲,修改,也可以與它進行互動。

可以使用__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中的類不過是更大類的另一個對象。

Python進階丨如何建立你的第一個Python元類?

類為對象定義規則。同樣,元類負責為類配置設定行為。我們已經知道,類是對象,就像每個對象都有一個執行個體一樣,類是元類的執行個體。

但是也有像Ruby和Objective-C這樣的語言也支援元類。那麼,是什麼使Python Metaclass更好,為什麼還要學習它呢?答案是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中的所有内容都有與之關聯的類型。在下一個主題中,我們将嘗試了解元類實際上是如何工作的。

每當建立一個類時,都會調用預設的Metaclass類型。 元類包含名稱,基類集以及與該類關聯的屬性等資訊。是以,在執行個體化一個類時,将調用帶有這些參數的類。可以通過兩種方法建立元類:

  1. 自定義元類

讓我們繼續輸入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類:

Python進階丨如何建立你的第一個Python元類?

當我們通過類型類傳遞參數時,它使用以下文法。

type(__name__, __base__, attributes)      
  • 名稱是一個字元串,并帶有類名
  • 該基礎是一個元組,可幫助建立子類
  • 屬性是字典,并配置設定鍵值對

由于Python中的類的行為與對象相似,是以可以用相同的方式更改其行為。我們可以在類内添加或删除方法,類似于對對象的處理方式。

現在您已經知道Metaclass在Python中建立了所有其他類,并使用類型class定義了它們的行為。但是,您一定想知道,我們還有其他方法可以建立元類嗎?是以,讓我們看看如何建立一個自定義的元類。

現在我們知道并了解類型類如何工作。現在該學習如何建立自定義元類了。我們可以通過執行動作或代碼注入來修改類的工作。為此,我們可以在建立類定義時将Metaclass作為關鍵字傳遞。另外,我們可以通過簡單地繼承通過此Metaclass關鍵字執行個體化的類來實作此目的。

在建立新類時,Python查找__metaclass__ 關鍵字。以防萬一,如果不存在。它遵循類型類層次結構。

Python進階丨如何建立你的第一個Python元類?

Python在命名空間中執行所有字典後,将調用類型對象,後者建立類的對象。我們可以使用兩種方法來建立自定義元類。

Python進階丨如何建立你的第一個Python元類?
class EduFirst(type):
def __new__(cls, name, base_cls, dict):
pass
class EduSecond(type):
def __init__(self, name, base_cls, dict):
pass      

讓我詳細解釋這兩種方法:

  1. __new __(): 當使用者要在類建立之前定義元組字典時使用。它傳回一個類的執行個體,并且很容易覆寫/管理對象流。
  2. __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

元類允許自定義類。還有多種其他有效且簡單得多的方法可以通過這些方法實作相同的輸出。這樣的例子之一就是使用裝飾器。

Decorator是Python的一項流行功能,它允許您向代碼中添加更多功能。裝飾器是可調用的對象,可幫助修改現有的類甚至函數。在編譯期間,部分代碼将調用并修改另一部分。此過程也稱為元程式設計。

Python進階丨如何建立你的第一個Python元類?
def decorator(cls):
class NewClass(cls):
attribute = 200
 return NewClass
@decorator
Class Test1:
 pass
@decorator
 
Class Test2:
 pass
Test1.attribute
 
Test2.attribute      

Python中的Decorator是一個非常有用且功能強大的工具,可幫助您更改函數的行為,而無需實際更改任何代碼。 當您要在調試時修改程式的一部分而不是重寫函數或更改整個程式時,這非常友善。取而代之的是,您隻需編寫一個單行裝飾器,其餘的就由它來處理。

本文分享自華為雲社群《如何建立您的第一個Python元類?》,原文作者:Yuchuan。

點選關注,第一時間了解華為雲新鮮技術~