Python中type和object的关系
知乎上看到的提問:
兩個是互為實例的關系,但不是互為子類的關系,只有type是object的子類,反之則不成立。 大牛說兩者是蛋生雞雞生蛋的關系,但我還是不明白,有懂的麻煩解釋一下, 希望不要給出外文的鏈接。python為什么設計出兩個,去掉一個行不行?下面是jeff kit的回答:
給別人講解過很多次,但寫成文字是第一次。試一試吧,自己主要也是看了這篇文章(Python Types and Objects)才懂的。object 和 type的關系很像雞和蛋的關系,先有object還是先有type沒法說,obejct和type是共生的關系,必須同時出現(xiàn)的。在看下去之前,也要請先明白,在Python里面,所有的東西都是對象的概念。在面向對象體系里面,存在兩種關系:- 父子關系,即繼承關系,表現(xiàn)為子類繼承于父類,如『蛇』類繼承自『爬行動物』類,我們說『蛇是一種爬行動物』,英文說『snake is a kind of reptile』。在python里要查看一個類型的父類,使用它的bases屬性可以查看。- 類型實例關系,表現(xiàn)為某個類型的實例化,例如『萌萌是一條蛇』,英文說『萌萌 is an instance of snake』。在python里要查看一個實例的類型,使用它的class屬性可以查看,或者使用type()函數(shù)查看。這兩種關系使用下面這張圖簡單示意,繼承關系使用實線從子到父連接,類型實例關系使用虛線從實例到類型連接:
我們將使用一塊白板來描述一下Python里面對象的關系,白板劃分成三列:
先來看看type和object:
>>> object <type 'object'> >>> type <type 'type'>它們都是type的一個實例,表示它們都是類型對象。
在Python的世界中,object是父子關系的頂端,所有的數(shù)據(jù)類型的父類都是它;type是類型實例關系的頂端,所有對象都是它的實例的。它們兩個的關系可以這樣描述:
- object是一個type,object is an instance of type。即Object是type的一個實例。
- type是一種object, type is kind of object。即Type是object的子類。
此時,白板上對象的關系如下圖:
我們再引入list, dict, tuple 這些內置數(shù)據(jù)類型來看看:
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> list.__bases__ (<type 'object'>,) >>> list.__class__ <type 'type'> >>> dict.__bases__ (<type 'object'>,) >>> dict.__class__ <type 'type'> >>> tuple.__class__ <type 'type'> >>> tuple.__bases__ (<type 'object'>,)它們的父類都是object,類型都是type。
再實例化一個list看看:
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> mylist = [1,2,3] >>> mylist.__class__ <type 'list'> >>> mylist.__bases__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'list' object has no attribute '__bases__'實例化的list的類型是<type ‘list’>, 而沒有了父類。
把它們加到白板上去:
白板上的虛線表示源是目標的實例,實線表示源是目標的子類。即,左邊的是右邊的類型,而上面的是下面的父親。
虛線是跨列產生關系,而實線只能在一列內產生關系。除了type和object兩者外。
當我們自己去定個一個類及實例化它的時候,和上面的對象們又是什么關系呢?試一下:
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> class C(object): ... pass ... >>> C.__class__ <type 'type'> >>> C.__bases__ (<type 'object'>,)實例化
>>> c = C() >>> c.__class__ <class '__main__.C'> >>> c.__bases__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'C' object has no attribute '__bases__'這個實例化的C類對象也是沒有父類的屬性的。
再更新一下白板:
白板上的第一列,目前只有type,我們先把這列的東西叫Type。
白板上的第二列,它們既是第三列的類型,又是第一列的實例,我們把這列的對象叫TypeObject。
白板上的第三列,它們是第二列類型的實例,而沒有父類(bases)的,我們把它們叫Instance。
你以為事情就這樣完了?不。。看見type孤零零在第一列其實不是那么舒服。。我們給它整幾個玩伴看看。但要怎么整呢?要屬于第一列的,必須是type的子類,那么我們只需要繼承type來定義類就可以了:
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> class M(type): ... pass ...? >>> M.__class__ <type 'type'> >>> M.__bases__ (<type 'type'>,) >>>嗯嗯,M類的類型和父類都是type。這個時候,我們可以把它歸到第一列去。那么,要怎么樣實例化M類型呢?實例化后它應該出現(xiàn)在那個列?嗯嗯,好吧,剛才你一不小心創(chuàng)建了一個元類,MetaClass!即類的類。如果你要實例化一個元類,那還是得定義一個類:
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> class TM(object): ... __metaclass__ = M # 這樣來指定元類。 ...? ...? >>> TM.__class__ <class '__main__.M'> # 這個類不再是type類型,而是M類型的。 >>> TM.__bases__ (<type 'object'>,)好了,現(xiàn)在TM這個類就是出現(xiàn)在第二列的。
再總結一下:
第一列,元類列,type是所有元類的父親。我們可以通過繼承type來創(chuàng)建元類。
第二列,TypeObject列,也稱類列,object是所有類的父親,大部份我們直接使用的數(shù)據(jù)類型都存在這個列的。
第三列,實例列,實例是對象關系鏈的末端,不能再被子類化和實例化。
到現(xiàn)在為止,Python類型的秘密已經(jīng)說穿了,不一小心連元類也暴露了。哎。慢慢消化吧,信息量很大。
總結
以上是生活随笔為你收集整理的Python中type和object的关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python之简单的get和post请求
- 下一篇: Python的Super方法