溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

在python中PyType_Type和PyBaseObject_Type有什么區(qū)別

發(fā)布時間:2021-06-16 13:41:17 來源:億速云 閱讀:324 作者:chen 欄目:開發(fā)技術(shù)

這篇文章主要講解了“在python中PyType_Type和PyBaseObject_Type有什么區(qū)別”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“在python中PyType_Type和PyBaseObject_Type有什么區(qū)別”吧!

PyType_Type和PyBaseObject_Type

PyObject和PyTypeObject內(nèi)容的最后指出下圖中對實例對象類型對象的理解是不完全正確的,

在python中PyType_Type和PyBaseObject_Type有什么區(qū)別

浮點類型對象全局唯一,Python在C語言層面實現(xiàn)過程中將其定義為一個全局靜態(tài)變量,定義于Object/floatobject.c中,命名為PyFloat_Type。

PyTypeObject PyFloat_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "float",
    sizeof(PyFloatObject),
    0,
    (destructor)float_dealloc,                  /* tp_dealloc */

    // ...
    (reprfunc)float_repr,                       /* tp_repr */

    // ...
};
  • 第2行使用初始化ob_refcntob_type以及ob_size三個字段,PyVarObject_HEAD_INIT的定義可以參考博文1.4.3節(jié)的內(nèi)容。

  • 第3行將tp_name字段初始化成類型名稱"float"

  • 再往下是各種操作的函數(shù)指針

ob_type指針指向PyType_Type,這也是一個靜態(tài)定義的全局變量。代表“類型的類型” 的type對象就是PyType_Type

一. 類型的類型—PyType_Tpye(type的實體)

上文中,float類型對象在底層實現(xiàn)過程中對應(yīng)PyFloat_Type全局靜態(tài)變量。Python類型是一種對象,也有自己的類型,即Python中的type。

>>> float.__class__
<class 'type'>

自定義類型也遵循同樣的規(guī)則,

>>> class Foo(object):
...     pass
...
>>> Foo.__class__
<class 'type'>

在查看PyFloat_Type代碼實現(xiàn)時,ob_type字段指向的PyType_Type就是type的實現(xiàn)。在Object/typeobject.c中定義,

PyTypeObject PyType_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "type",                                     /* tp_name */
    sizeof(PyHeapTypeObject),                   /* tp_basicsize */
    sizeof(PyMemberDef),                        /* tp_itemsize */
    (destructor)type_dealloc,                   /* tp_dealloc */

    // ...
    (reprfunc)type_repr,                        /* tp_repr */

    // ...
};
  • 內(nèi)建類型和自定義類的PyTypeObject對象都是通過PyType_Type創(chuàng)建。PyType_TypePyTypeObject的一個實例。

  • PyType_Type是類型機制中至關(guān)重要的對象,是所有類型的類型,稱為元類型

  • 第2行代碼處PyType_Type將自身的ob_type字段指向它自己。

>>> type.__class__
<class 'type'>
>>> type.__class__ is type
True

由此,以float為例,可以繪制一個更完善但是并不完全正確的實例對象和類型對象在內(nèi)存中的關(guān)系圖,

在python中PyType_Type和PyBaseObject_Type有什么區(qū)別

二. 類型之基—PyBaseObject_Type(object的實體)

上一節(jié)中紅色標(biāo)記的語句,并不完全正確是因為思考過程中忽略了object對象的存在。

object是另一個特殊的類型,是所有類型的基類。同樣可以通過PyFloat_Typetp_base字段順藤摸瓜找到。然而,在源碼的第2行的PyVarObject_HEAD_INIT定義中,該字段并沒有初始化,

0,                                          /* tp_base */

更進一步查找代碼中PyFloat_Type出現(xiàn)的地方,在Object/object.c中發(fā)現(xiàn)如下代碼,

if (PyType_Ready(&PyFloat_Type) < 0)
    Py_FatalError("Can't initialize float type");

創(chuàng)建類型對象過程中,需要PyType_Ready方法將tp_base字段初始化,具體如下

int
PyType_Ready(PyTypeObject *type)
{
    // ...

    base = type->tp_base;
    if (base == NULL && type != &PyBaseObject_Type) {
        base = type->tp_base = &PyBaseObject_Type;
        Py_INCREF(base);
    }

    // ...
}

PyFloat_Type中的tp_base字段初始化成PyBaseObject_Type,它就是object背后的實體,其源碼定義為,

PyTypeObject PyBaseObject_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "object",                                   /* tp_name */
    sizeof(PyObject),                           /* tp_basicsize */
    0,                                          /* tp_itemsize */
    object_dealloc,                             /* tp_dealloc */

    // ...
    object_repr,                                /* tp_repr */
};

源碼中ob_type字段指向PyType_Type這與下方object在 Python中的測試代碼相吻合,

>>> object.__class__
<class 'type'>

此外,PyType_Ready函數(shù)初始化PyBaseObject_Type時,不設(shè)置tp_base字段。 因為繼承鏈必須有一個終點,否則沿著繼承鏈查找時會陷入死循環(huán)。

>>> print(object.__base__)
None

由此,得到了實例對象和類型對象在內(nèi)存中完整的關(guān)系圖。以float為例,

在python中PyType_Type和PyBaseObject_Type有什么區(qū)別

感謝各位的閱讀,以上就是“在python中PyType_Type和PyBaseObject_Type有什么區(qū)別”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對在python中PyType_Type和PyBaseObject_Type有什么區(qū)別這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI