懵了!
知乎有個很有意思的問題,type()是函數(shù)還是類,萌新遇到這個問題還真有點(diǎn)懵。
先說結(jié)論,type 不是函數(shù)(對象), type 是類(對象),而且是元類(不理解什么是元類的先忽略),但我們平常說它是函數(shù)問題也不大。
直接打印type看看是什么鬼
>>> type
>>>和自定義類一樣,都是類(class)
>>> class Person:
... pass
...
>>> Person
<class '__main__.Person'>而函數(shù)是這樣的
>>> def fun():
... pass
...
>>> fun
0x0000021636AD4A68 >
>>>函數(shù)和類都是callable對象,callable 叫可調(diào)用對象,所謂可調(diào)用對象就是可以被調(diào)用(后面有一對括號)例如:
fun()
sum(xxx)
type(xxx)判斷一個對象是不是callable對象可以使用函數(shù):
>>> callable(type)
True
>>> callable(str)
True
>>> callable("abc")
False很多人誤以為只要可被調(diào)用就是函數(shù),其實(shí)類也被調(diào)用,實(shí)例對象也可以被調(diào)用。只要實(shí)現(xiàn)了__call__方法的對象都是可被調(diào)用對象。
回答了問題后,再來說說type的作用
type的第一個作用是用來查看對象的類型,格式是:
type(object)例如:
>>> type(1)
>>> type([])
>>> type({})
>>>不過,平常我們判斷對象的類型通常會使用 isinstance 函數(shù)
>>> isinstance(1, int)
True
>>> isinstance(True, int)
True
>>> isinstance(True, bool)
True用isinstance的好處是能處理子類的情況,你看,True 既是bool類型也是int類型,因?yàn)?bool是int的子類。
type 的第二個作用是用來創(chuàng)建類的
我們知道,實(shí)例對象是類創(chuàng)建的,那類又是誰創(chuàng)建的呢,答案是元類。舉個例子吧
>>> type(1)
>>> type(int)
整數(shù)1是實(shí)例對象,它是由int類創(chuàng)建的,而int類也是個對象(萬物皆對象),它由誰創(chuàng)建的,是 type 類。

type 就是元類,用來創(chuàng)建類的類就是元類。
平常我們都是使用關(guān)鍵字 class 來定義類,例如:
>>> class Foo:
... a = 1
...其實(shí),我們還可以用type來創(chuàng)建類,不是說過type是元類嘛。
格式是:
type(name, bases, dict)name 是類的名字, bases 是要繼承的父類集合, dict 是這個類的屬性集合。
現(xiàn)在我們用 type 函數(shù)來創(chuàng)建它 。
>>> Foo = type("Foo", (object,), {"a":1})
>>> Foo
>>> Foo.a
1看到了嗎,用type創(chuàng)建的類其實(shí)和前面用class關(guān)鍵字創(chuàng)建的類效果是一樣的。
那么什么時候會用到元類呢?
“元類就是深度的魔法,99%的用戶應(yīng)該根本不必為此操心。如果你想搞清楚究竟是否需要用到元類,那么你就不需要它。那些實(shí)際用到元類的人都非常清楚地知道他們需要做什么,而且根本不需要解釋為什么要用元類。”? —— Python界的領(lǐng)袖 Tim Peters
1%就是那些寫框架的人。
推薦:
