python的type和object之間是怎麼一種關係?

來源:互聯網
上載者:User
是初學者請勿噴啊
兩個是互為執行個體的關係,但不是互為子類的關係,只有type是object的子類,反之則不成立。大牛說兩者是蛋生雞雞生蛋的關係,但我還是不明白,有懂的麻煩解釋一下,希望不要給出外文的連結。python為什麼設計出兩個,去掉 一個行不行?

回複內容:

給別人講解過很多次,但寫成文字是第一次。試一試吧,自己主要也是看了這篇文章(Python Types and Objects)才懂的。

object 和 type的關係很像雞和蛋的關係,先有object還是先有type沒法說,obejct和type是共生的關係,必須同時出現的。

在看下去之前,也要請先明白,在Python裡面,所有的東西都是對象的概念。

在物件導向體系裡面,存在兩種關係:
- 父子關係,即繼承關係,表現為子類繼承於父類,如『蛇』類繼承自『爬行動物』類,我們說『蛇是一種爬行動物』,英文說『snake is a kind of reptile』。在python裡要查看一個類型的父類,使用它的__bases__屬性可以查看。
- 類型執行個體關係,表現為某個類型的執行個體化,例如『萌萌是一條蛇』,英文說『萌萌 is an instance of snake』。在python裡要查看一個執行個體的類型,使用它的__class__屬性可以查看,或者使用type()函數查看。

這兩種關係使用下面這張圖簡單示意,繼承關係使用實線從子到父串連,類型執行個體關係使用虛線從執行個體到類型串連:


我們將使用一塊白板來描述一下Python裡面對象的關係,白板劃分成三列:

先來看看type和object:
>>> object

>>> type

它們都是type的一個執行個體,表示它們都是類型對象。

在Python的世界中,object是父子關係的頂端,所有的資料類型的父類都是它;type是類型執行個體關係的頂端,所有對象都是它的執行個體的。它們兩個的關係可以這樣描述:
- object是一個type,object is and instance of type。即Object是type的一個執行個體。

>>> object.__class__

>>> object.__bases__ # object 無父類,因為它是鏈條頂端。
()
- type是一種object, type is kind of object。即Type是object的子類。

>>> type.__bases__
(,)
>>> type.__class__ # type的類型是自己


此時,白板上對象的關係如:


我們再引入list, dict, tuple 這些內建資料類型來看看:
>>> list.__bases__
(,)
>>> list.__class__

>>> dict.__bases__
(,)
>>> dict.__class__

>>> tuple.__class__

>>> tuple.__bases__
(,)
它們的父類都是object,類型都是type。

再執行個體化一個list看看:
>>> mylist = [1,2,3]
>>> mylist.__class__

>>> mylist.__bases__
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'list' object has no attribute '__bases__'
執行個體化的list的類型是, 而沒有了父類。

把它們加到白板上去:
白板上的虛線表示源是目標的執行個體,實線表示源是目標的子類。即,左邊的是右邊的類型,而上面的是下面的父親。白板上的虛線表示源是目標的執行個體,實線表示源是目標的子類。即,左邊的是右邊的類型,而上面的是下面的父親。
虛線是跨列產生關係,而實線只能在一列內產生關係。除了type和object兩者外。

當我們自己去定個一個類及執行個體化它的時候,和上面的對象們又是什麼關係呢?試一下:

>>> class C(object):
... pass
...
>>> C.__class__

>>> C.__bases__
(,)

執行個體化
>>> c = C()
>>> c.__class__

>>> c.__bases__
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'C' object has no attribute '__bases__'
這個執行個體化的C類對象也是沒有父類的屬性的。
再更新一下白板:
白板上的第一列,目前只有type,我們先把這列的東西叫Type。白板上的第一列,目前只有type,我們先把這列的東西叫Type。
白板上的第二列,它們既是第三列的類型,又是第一列的執行個體,我們把這列的對象叫TypeObject。
白板上的第三列,它們是第二列類型的執行個體,而沒有父類(__bases__)的,我們把它們叫Instance。

你以為事情就這樣完了?不。。看見type孤零零在第一列其實不是那麼舒服。。我們給它整幾個玩伴看看。但要怎麼整呢?要屬於第一列的,必須是type的子類,那麼我們只需要繼承type來定義類就可以了:
>>> class M(type):
... pass
...
>>> M.__class__

>>> M.__bases__
(,)
>>>
嗯嗯,M類的類型和父類都是type。這個時候,我們可以把它歸到第一列去。那麼,要怎麼樣執行個體化M類型呢?執行個體化後它應該出現在那個列?嗯嗯,好吧,剛才你一不小心建立了一個元類,MetaClass!即類的類。如果你要執行個體化一個元類,那還是得定義一個類:
>>> class TM(object):
... __metaclass__ = M # 這樣來指定元類。
...
...
>>> TM.__class__
# 這個類不再是type類型,而是M類型的。
>>> TM.__bases__
(,)

好了,現在TM這個類就是出現在第二列的。

再總結一下:
第一列,元類列,type是所有元類的父親。我們可以通過繼承type來建立元類。
第二列,TypeObject列,也稱類列,object是所有類的父親,大部份我們直接使用的資料類型都存在這個列的。
第三列,執行個體列,執行個體是對象關係鏈的末端,不能再被子類化和執行個體化。

到現在為止,Python類型的秘密已經說穿了,不一小心連元類也暴露了。哎。慢慢消化吧,資訊量很大。

如果轉述版看不懂,那麼去啃一啃原文的吧:(Python Types and Objects)

=============更新=============
更新更新。。回答一下題主在問題後面說的為什麼要有兩個,而不是一個。
如果type和object只保留一個,那麼一定是object。只有object 時,第一列將不複存在,只剩下二三列,第二列表示類型,第三列表示執行個體,這個和大部分靜態語言的類型架構類似,如java 。
這樣的架構將讓python 失去一種很重要的動態特性--動態建立類型。本來,類(第二列的同學)在Python裡面是一個對象(typeobject),對象是可以在運行時動態修改的,所以我們能在你定義一個類之後去修改他的行為或屬性!拿掉第一列後,第二列變成了純類型,寫成怎樣的,運行時行為就怎樣。在這一點上,並不比靜態語言有優勢。
所以,以上!那我就來補充個跟實現思路相關的傳送門吧:先有Class還是先有Object? - RednaxelaFX 的回答
<- 這個傳送門雖然開頭講的是Java的情況,但後面也有講Python和Ruby,相信能解答題主的一些疑惑。我先放張圖

圖對不對先不管。我們先來看看 type 和 object 分別是什麼。

type 實際上是:
#define PyVarObject_HEAD_INIT(type, size)       \    1, type, size,PyTypeObject PyType_Type = {    PyVarObject_HEAD_INIT(&PyType_Type, 0)    "type",                                     /* tp_name */    sizeof(PyHeapTypeObject),                   /* tp_basicsize */    sizeof(PyMemberDef),                        /* tp_itemsize */    0,                                          /* tp_base */    ...}
謝邀,object是type(object的類型是type),type也是object(type繼承自object)
>>> isinstance(object, type)True>>> isinstance(type, object)True
這部分我當初是讀MSDN裡關於C Sharp的Object 和 type 的關係讀懂的……你如果手邊有Jeffery的《CLR via C#》 可以讀一下。專門為了這個問題去買一本可能有點奢侈,不過如果你是 .net 程式員,我推薦你收一本。

簡單的說,很多運行時體系(不一定是針對某種語言)都提供在運行時擷取類型資訊的功能,那麼擷取出來的是什麼東西呢?擷取出來的是一個描述類型資訊的對象。那麼所有描述類型資訊的對象,都是“類型”這個類型的執行個體。這個type類型不是類型本身,而是用於描述類型的對象執行個體, 類型本身是一種抽象的資訊,type類的執行個體對象是它具體的資訊載體。既然type類型也是一種類型,那麼它是公用根類型object的一個派生,也就是合情合理的設計了。

反過來, object 類型並不依賴 type 類型,最多它的一些反射/自省邏輯需要調用type。object是一種類型,type是描述類型的類型。
  1. 所有對象都一定是某一個類的執行個體
  2. 在python中類也是對象,所有類都是type元類的執行個體
  3. type元類也是對象,它是它自己的執行個體,它的父類是object
  4. object是類,它是type的執行個體,object沒有父類

我想這大概是是為了完成完全的物件導向,既然萬物都是對象,那最源頭的對象又是誰的執行個體?type和object很好地解決了這個問題:抓著自己的鞋帶把自己提起來(bootstrap)。

python新手,說錯請指正。Python中一切皆對象,凡事對象都有類型。
從cpython/object.h at 2.7 · python/cpython · GitHub
/* PyObject_HEAD defines the initial segment of every PyObject. */#define PyObject_HEAD                   \    _PyObject_HEAD_EXTRA                \    Py_ssize_t ob_refcnt;               \    struct _typeobject *ob_type;
既不是互為執行個體:
>>> object.__class__

>>> type.__class__

也不是互為子類:
>>> object.__bases__
()
>>> type.__bases__
(,)

type和object都是type的執行個體,而type是object的子類。

__class__是這兩個關係中更基本的一個。所有Python對象都有對應的class對象,而對一個Python的幾乎所有操作,即使是訪問對象屬性o.a這麼基本的,都是轉交給其class對象執行。唯二的例外,是__class__和id,這兩個操作的語義無法被class對象改變。在這方面,Python的可定製程度比絕大部分OOPL要高。

type是所有class對象的class,也稱為metaclass。它決定了你直接操作class對象(而不是通過其執行個體)時的行為。例如:
class C(object):    a = 1    def f(self):        passc = C()c.f() # 行為由C決定C.a # 行為由type決定
之前讀過一篇討論這個問題文章,連結已經丟了。。。建議題主讀一讀《Ruby元編程》,這本書對類和對象有較清晰和深入的討論,要求不高,Ruby和Python的物件模型非常相似,不懂Ruby也能讀懂。

要搞懂這個問題, 首先要先把類、類型、對象這些概念全部舍掉,重構世界觀。

首先,python裡面一切皆是對象,包括type、object、所有class,全部都是對象,

那對象之間靠什麼聯絡在一起呢?沒錯,靠的就是關係:
Python的世界裡,對象之間一共有兩種關係:

1、繼承關係:
比如有class A和class B(A),再強調一下,A和B都是對象,
則對象B繼承了對象A,或者說A是B的超類,
繼承關係可以通過__base__屬性得知,
>>> B.__base__<class 'A'>
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.