首頁 > 軟體

深入理解Python的元類

2021-11-25 19:02:01

什麼是元類

Python中,一切皆物件,我們定義的數位、字串、函數、列表等都是物件,物件是類(class)的是範例,而類(class)其實也是物件,是type的範例。這個type就是Python中的元類metaclass)。所謂元類就是用於建立所有型別的類,Python中的所有新式類以及Python3中的所有類都是type元類的範例。我們看下面這個例子:

print(type(0))  # <class 'int'>
print(type(int))  # <class 'type'>
print(type("tigeriaf"))  # <class 'str'>
print(type(str))  # <class 'type'>
print(type([1, 2, 3]))  # <class 'list'>
print(type(list))  #  <class 'type'>
class User:
    pass
u = User()
print(type(u))  # <class '__main__.User'>
print(type(User))  # <class 'type'>
print(type(type))  # <class 'type'>

type元類動態建立類

之前我們定義類要使用class關鍵字進行建立,除了這樣我們還可以使用type動態的去建立類。

用法如下:

type(name, bases, dict),接收三個引數

  • 第一個引數name是指要建立類的名稱
  • 第二個引數bases是指需要繼承父類別的元組
  • 第三個引數dict是類的屬性

例如:

class User:
    def __init__(self):
        self.name = 'tigeriaf'
print(User)
user = User()
print(user.name)
class User:
    def __init__(self):
        self.name = 'tigeriaf'
print(User)
user = User()
print(user.name)

以上兩種方式都可以建立類,輸出結果也是一樣的,可見使用type動態的去建立類也是非常方便的。

自定義元類

通過上面的例子我們知道可以使用type(name, bases, dict)來建立類,如果當使用type元類無法滿足我們的一些需求時,我們可以自定義一個元類並使用該元類去建立類嗎?答案是可以的,下面我們來看一下:

class MyMetaClass(type):
    def __init__(cls, name, bases, dict):
        super().__init__(name, bases, dict)
        cls.int_attrs = {}
        for k, v in dict.items():
            if type(v) is int:
                cls.int_attrs[k] = v
User = MyMetaClass('User', (), {'name': 'tigeriaf', "age": 24, "level": 2, "introduction": "Python全菜工程師"})
print(User)  # <class '__main__.User'>
user = User()  
print(user.name)  # tigeriaf
print(user.int_attrs)  # {'age': 24, 'level': 2}

也可以使用下面這種方法,去建立繼承元類的類。

class User(metaclass=MyMetaClass):
    pass

注意:在Python2中使用元類需要在要建立的類內對__metaclass__進行賦值,值為元類。

上述程式碼定義一個類MyMetaClass,繼承自type類,因為type是元類,所以MyMetaClass也是一個元類,在__init__通過super().__init__(name, bases, dict)呼叫了父類別type的__init__()方法,在實現自定義元類的基礎上,還在建立類的時候把屬性迴圈了一遍,然後值為int型別的屬性單獨存了起來。這樣我們就實現了比type元類更客製化化的元類了,我們可以隨意在元類內新增我們想要的功能。

總結

總體下來,發現元類及其使用有些難以理解且看不出有什麼特別的地方能讓我們去使用,好吧,確實如此,通常情況下確實可能用不到它,其實元類主要就是在類和範例建立的時候發揮作用,來實現一些功能,如果確實不清楚什麼時候該去使用的話,那我們就不需要它,當真正需要它的時候,我們可能就會發現它的強大之處。

本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!


IT145.com E-mail:sddin#qq.com