什么是元類
通過上面的介紹,終于模模糊糊的帶到元類這里來了。可是我們到現(xiàn)在還不知道元類是什么東東。
我們創(chuàng)建類的時候,大多數(shù)是為了創(chuàng)建類的實例對象。那么元類呢?元類就是用來創(chuàng)建類的。也可以換個理解方式就是:元類就是類的類。
通過上面 type() 函數(shù)的介紹,我們知道可以通過 type() 函數(shù)創(chuàng)建類:
MyClass = type('MyClass', (), {})
實際上 type() 函數(shù)是一個元類。type() 就是 Python 在背后用來創(chuàng)建所有類的元類。
那么現(xiàn)在我們也可以猜到一下為什么 type() 函數(shù)是 type 而不是 Type呢?
這可能是為了和 str 保持一致性,str 是用來創(chuàng)建字符串對象的類,而 int 是用來創(chuàng)建整數(shù)對象的類。type 就是創(chuàng)建類對象的類。你可以通過檢查 __class__ 屬性來看到這一點。Python 中所有的東西,注意喔,這里是說所有的東西,他們都是對象。這包括整數(shù)、字符串、函數(shù)以及類。它們?nèi)慷际菍ο?,而且它們都是從一個類創(chuàng)建而來。
# 整形 age = 23 print(age.__class__) # 字符串 name = '兩點水' print(name.__class__) # 函數(shù) def fu(): pass print(fu.__class__) # 實例 class eat(object): pass mEat = eat() print(mEat.__class__)
輸出的結(jié)果如下:
<class 'int'> <class 'str'> <class 'function'> <class '__main__.eat'>
可以看到,上面的所有東西,也就是所有對象都是通過類來創(chuàng)建的,那么我們可能會好奇,__class__ 的 __class__ 會是什么呢?換個說法就是,創(chuàng)建這些類的類是什么呢?
我們可以繼續(xù)在上面的代碼基礎(chǔ)上新增下面的代碼:
print(age.__class__.__class__) print(name.__class__.__class__) print(fu.__class__.__class__) print(mEat.__class__.__class__)
輸出的結(jié)果如下:
<class 'type'> <class 'type'> <class 'type'> <class 'type'>
認(rèn)真觀察,再理清一下,上面輸出的結(jié)果是我們把整形 age ,字符創(chuàng) name ,函數(shù) fu 和對象實例 mEat 里 __class__ 的 __class__ 打印出來的結(jié)果。也可以說是他們類的類打印結(jié)果。發(fā)現(xiàn)打印出來的 class 都是 type 。
一開始也提到了,元類就是類的類。也就是元類就是負(fù)責(zé)創(chuàng)建類的一種東西。你也可以理解為,元類就是負(fù)責(zé)生成類的。而 type 就是內(nèi)建的元類。也就是 Python 自帶的元類。