91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

在python中PyType_Type和PyBaseObject_Type有什么區別

發布時間:2021-06-16 13:41:17 來源:億速云 閱讀:330 作者:chen 欄目:開發技術

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

PyType_Type和PyBaseObject_Type

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

在python中PyType_Type和PyBaseObject_Type有什么區別

浮點類型對象全局唯一,Python在C語言層面實現過程中將其定義為一個全局靜態變量,定義于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節的內容。

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

  • 再往下是各種操作的函數指針

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

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

上文中,float類型對象在底層實現過程中對應PyFloat_Type全局靜態變量。Python類型是一種對象,也有自己的類型,即Python中的type。

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

自定義類型也遵循同樣的規則,

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

在查看PyFloat_Type代碼實現時,ob_type字段指向的PyType_Type就是type的實現。在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 */

    // ...
};
  • 內建類型和自定義類的PyTypeObject對象都是通過PyType_Type創建PyType_TypePyTypeObject的一個實例。

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

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

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

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

在python中PyType_Type和PyBaseObject_Type有什么區別

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

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

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

0,                                          /* tp_base */

更進一步查找代碼中PyFloat_Type出現的地方,在Object/object.c中發現如下代碼,

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

創建類型對象過程中,需要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函數初始化PyBaseObject_Type時,不設置tp_base字段。 因為繼承鏈必須有一個終點,否則沿著繼承鏈查找時會陷入死循環。

>>> print(object.__base__)
None

由此,得到了實例對象和類型對象在內存中完整的關系圖。以float為例,

在python中PyType_Type和PyBaseObject_Type有什么區別

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泸州市| 定结县| 商水县| 华池县| 高邮市| 龙泉市| 扎兰屯市| 鸡西市| 志丹县| 甘孜县| 望城县| 监利县| 桃园县| 英山县| 邯郸市| 清丰县| 宝兴县| 怀柔区| 通山县| 囊谦县| 双辽市| 民县| 德保县| 邢台县| 扬州市| 文登市| 南汇区| 松江区| 西乌珠穆沁旗| 渭源县| 东源县| 惠来县| 南京市| 湟中县| 茂名市| 鄂托克旗| 靖州| 随州市| 曲麻莱县| 龙山县| 西和县|