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