python中的元類(metaclass)

關於元類,實際上很少會用到,但是瞭解一下也是有必要的,因爲元類個很神奇的東西。

python中的類

在大多數編程語言中,類就是一組用來描述如何生成一個對象的代碼段。在Python中這一點仍然成立。但是,Python中的類也是一種對象。只要你使用關鍵字class,Python解釋器在執行的時候就會創建一個對象。下列代碼:

 class ObjectCreator(object):
      pass

將在內存中創建一個對象,名字就是ObjectCreator。這個對象(類)自身擁有創建對象(類實例)的能力,這說明它是一個類,但它的本質仍然是一個對象。

神奇的type方法

還記得內建函數type嗎?這個古老但強大的函數能夠讓你知道一個對象的類型是什麼,就像這樣:

print(type(1))               #<class 'int'>
print(type('1'))             #<class 'str'>
print(type(ObjectCreator))   #<class 'type'>
print(type(ObjectCreator())) #<class '__main__.ObjectCreator'>

此外,type還有一種完全不同的能力,它能動態的創建類。type可以接受一個類的描述作爲參數,然後返回一個類。
type可以像這樣工作:

type(類名, 父類的元組(針對繼承的情況,可以爲空),包含屬性的字典(名稱和值))

示例:

MyClass = type('MyClass', (), {'author':'trophy'})  # 返回一個類對象
print(MyClass)          #<class '__main__.MyClass'>
print(MyClass.author)   #trophy
print(MyClass())        #<__main__.MyClass object at 0x0000001FD980>

你可以看到,在Python中,類也是對象,你可以動態的創建類。這就是當你使用關鍵字class時Python在幕後做的事情,而這就是通過元類來實現的。

到底什麼是元類

Python中的類也是對象,那麼元類就是用來創建這些類(對象)的,元類就是類的類
type就是Python在背後用來創建所有類的元類。我們都知道,str是用來創建字符串對象的類,int是用來創建整數對象的類。type就是創建類對象的類,你可以通過檢查__class__屬性來看到這一點。Python中所有的東西都是對象,這包括整數、字符串、函數以及類。它們全部都是對象,而且它們都是從一個類(元類type)創建而來。
看完下面的例子就懂了:

a = 1
print(a.__class__)              #<class 'int'>
print(a.__class__.__class__)    #<class 'type'>
b = 'hello'
print(b.__class__)              #<class 'str'>
print(b.__class__.__class__)    #<class 'type'>
c = type('NewClass', (), {})
print(c().__class__)            #<class '__main__.NewClass'>
print(c().__class__.__class__)  #<class 'type'>

元類的使用

一般來說,我們根本就用不上元類

元類就是深度的魔法,99%的用戶應該根本不必爲此操心。如果你想搞清楚究竟是否需要用到元類,那麼你就不需要它。那些實際用到元類的人都非常清楚地知道他們需要做什麼,而且根本不需要解釋爲什麼要用元類。” —— Python界的領袖 Tim Peters

元類的主要用途是創建API。一個典型的例子是Django ORM,好奇的自己去google瞭解瞭解吧~


參考原文:深刻理解Python元類

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章