• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Python源码学习之PyType_Type和PyBaseObject_Type详解

    PyType_Type和PyBaseObject_Type

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

    浮点类型对象全局唯一,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 */
    
        // ...
    };
    

    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 */
    
        // ...
    };
    
    >>> type.__class__
    class 'type'>
    >>> type.__class__ is type
    True

    由此,以float为例,可以绘制一个更完善但是并不完全正确的实例对象和类型对象在内存中的关系图,

    二. 类型之基—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详解的文章就介绍到这了,更多相关PyType_Type和PyBaseObject_Type内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • Python源码学习之PyObject和PyTypeObject
    • Python源码解析之List
    • python源码剖析之PyObject详解
    • python opencv人脸识别考勤系统的完整源码
    • python 制作手机归属地查询工具(附源码)
    • python基于tkinter制作无损音乐下载工具(附源码)
    • Python bsonrpc源码解读
    • Python制作脚本帮女朋友抢购清空购物车
    上一篇:pandas数据处理清洗实现中文地址拆分案例
    下一篇:pygame实现滑块接小球游戏
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Python源码学习之PyType_Type和PyBaseObject_Type详解 Python,源码,学,习之,PyType,