音效素材网提供各类素材,打造精品素材网站!

站内导航 站长工具 投稿中心 手机访问

音效素材

Python源码学习之PyType_Type和PyBaseObject_Type详解
日期:2021-09-08 14:44:02   来源:脚本之家

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内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

    您感兴趣的教程

    在docker中安装mysql详解

    本篇文章主要介绍了在docker中安装mysql详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编...

    详解 安装 docker mysql

    win10中文输入法仅在桌面显示怎么办?

    win10中文输入法仅在桌面显示怎么办?

    win10系统使用搜狗,QQ输入法只有在显示桌面的时候才出来,在使用其他程序输入框里面却只能输入字母数字,win10中...

    win10 中文输入法

    一分钟掌握linux系统目录结构

    这篇文章主要介绍了linux系统目录结构,通过结构图和多张表格了解linux系统目录结构,感兴趣的小伙伴们可以参考一...

    结构 目录 系统 linux

    PHP程序员玩转Linux系列 Linux和Windows安装

    这篇文章主要为大家详细介绍了PHP程序员玩转Linux系列文章,Linux和Windows安装nginx教程,具有一定的参考价值,感兴趣...

    玩转 程序员 安装 系列 PHP

    win10怎么安装杜比音效Doby V4.1 win10安装杜

    第四代杜比®家庭影院®技术包含了一整套协同工作的技术,让PC 发出清晰的环绕声同时第四代杜比家庭影院技术...

    win10杜比音效

    纯CSS实现iOS风格打开关闭选择框功能

    这篇文章主要介绍了纯CSS实现iOS风格打开关闭选择框,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作...

    css ios c

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的办法

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的

    Win7给电脑C盘扩容的办法大家知道吗?当系统分区C盘空间不足时,就需要给它扩容了,如果不管,C盘没有足够的空间...

    Win7 C盘 扩容

    百度推广竞品词的投放策略

    SEM是基于关键词搜索的营销活动。作为推广人员,我们所做的工作,就是打理成千上万的关键词,关注它们的质量度...

    百度推广 竞品词

    Visual Studio Code(vscode) git的使用教程

    这篇文章主要介绍了详解Visual Studio Code(vscode) git的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...

    教程 Studio Visual Code git

    七牛云储存创始人分享七牛的创立故事与

    这篇文章主要介绍了七牛云储存创始人分享七牛的创立故事与对Go语言的应用,七牛选用Go语言这门新兴的编程语言进行...

    七牛 Go语言

    Win10预览版Mobile 10547即将发布 9月19日上午

    微软副总裁Gabriel Aul的Twitter透露了 Win10 Mobile预览版10536即将发布,他表示该版本已进入内部慢速版阶段,发布时间目...

    Win10 预览版

    HTML标签meta总结,HTML5 head meta 属性整理

    移动前端开发中添加一些webkit专属的HTML5头部标签,帮助浏览器更好解析HTML代码,更好地将移动web前端页面表现出来...

    移动端html5模拟长按事件的实现方法

    这篇文章主要介绍了移动端html5模拟长按事件的实现方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家...

    移动端 html5 长按

    HTML常用meta大全(推荐)

    这篇文章主要介绍了HTML常用meta大全(推荐),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    cdr怎么把图片转换成位图? cdr图片转换为位图的教程

    cdr怎么把图片转换成位图? cdr图片转换为

    cdr怎么把图片转换成位图?cdr中插入的图片想要转换成位图,该怎么转换呢?下面我们就来看看cdr图片转换为位图的...

    cdr 图片 位图

    win10系统怎么录屏?win10系统自带录屏详细教程

    win10系统怎么录屏?win10系统自带录屏详细

    当我们是使用win10系统的时候,想要录制电脑上的画面,这时候有人会想到下个第三方软件,其实可以用电脑上的自带...

    win10 系统自带录屏 详细教程

    + 更多教程 +
    ASP编程JSP编程PHP编程.NET编程python编程