Python源码学习之PyType_Type和PyBaseObject_Type详解

 更新时间:2021年06月16日 10:15:42   作者:Jakob_Hu  
今天给大家带来的是关于Python源码的相关知识学习,文章围绕着PyType_Type和PyBaseObject_Type展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下

PyType_Type和PyBaseObject_Type

PyObject和PyTypeObject内容的最后指出下图中对实例对象类型对象的理解是不完全正确的,

Alt

浮点类型对象全局唯一,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为例,可以绘制一个更完善但是并不完全正确的实例对象和类型对象在内存中的关系图,

Alt

二. 类型之基—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为例,

Alt

到此这篇关于Python源码学习之PyType_Type和PyBaseObject_Type详解的文章就介绍到这了,更多相关PyType_Type和PyBaseObject_Type内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python对象的深拷贝和浅拷贝详解

    Python对象的深拷贝和浅拷贝详解

    这篇文章主要介绍了Python对象的深拷贝和浅拷贝详解,本文从Python核心编程2书中摘录而来,总结的比较精辟,需要的朋友可以参考下
    2014-08-08
  • opencv实现文档矫正

    opencv实现文档矫正

    这篇文章主要为大家详细介绍了opencv实现文档矫正功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • Numpy随机抽样的实现

    Numpy随机抽样的实现

    本文主要介绍了Numpy随机抽样的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • 使用python 爬虫抓站的一些技巧总结

    使用python 爬虫抓站的一些技巧总结

    这篇文章主要介绍了用 python 爬虫抓站的一些技巧总结,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2018-01-01
  • python实现的分层随机抽样案例

    python实现的分层随机抽样案例

    这篇文章主要介绍了python实现的分层随机抽样案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • pycharm+robot开发及配置指南

    pycharm+robot开发及配置指南

    这篇文章主要介绍了pycharm+robot开发指南,包括pycharm配置及robot的配置,本文给大家介绍的非常详细,需要的朋友可以参考下
    2021-09-09
  • 详解如何利用Python制作24点小游戏

    详解如何利用Python制作24点小游戏

    这篇文章主要为大家详细介绍了如何通过Python制作24点小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Python元类编程实现一个简单的ORM

    Python元类编程实现一个简单的ORM

    本文主要介绍了Python元类编程实现一个简单的ORM,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • 详解Python中的分支和循环结构

    详解Python中的分支和循环结构

    这篇文章主要介绍了Python中的分支和循环结构,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • 树莓派用python中的OpenCV输出USB摄像头画面

    树莓派用python中的OpenCV输出USB摄像头画面

    这篇文章主要为大家详细介绍了树莓派用python中的OpenCV输出USB摄像头画面,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06

最新评论