广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python源码学习之PyType_Type和PyBaseObject_Type详解
  • 919
分享到

Python源码学习之PyType_Type和PyBaseObject_Type详解

2024-04-02 19:04:59 919人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

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

PyType_Type和PyBaseObject_Type

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

Alt

浮点类型对象全局唯一pythonC语言层面实现过程中将其定义为一个全局静态变量,定义于Object/floatobject.c中,命名为PyFloat_Type


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

    // ...
    (reprfunc)float_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",                                     
    sizeof(PyHeapTypeObject),                   
    sizeof(PyMemberDef),                        
    (destructor)type_dealloc,                   

    // ...
    (reprfunc)type_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,                                          

更进一步查找代码中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",                                   
    sizeof(PyObject),                           
    0,                                          
    object_dealloc,                             

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

--结束END--

本文标题: Python源码学习之PyType_Type和PyBaseObject_Type详解

本文链接: https://www.lsjlt.com/news/128282.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python源码学习之PyType_Type和PyBaseObject_Type详解
    PyType_Type和PyBaseObject_Type PyObject和PyTypeObject内容的最后指出下图中对实例对象和类型对象的理解是不完全正确的, 浮点类型对象全...
    99+
    2022-11-12
  • Python源码学习之PyObject和PyTypeObject
    前言 Python是C语言实现的,因此Python对象在C语言层面应该是一个结构体 ,组织对象占用的内存。 不同类型的对象,数据及行为均可能不同,因此可以大胆猜测:不同类型的对象由不...
    99+
    2022-11-12
  • Python基础学习之函数和代码复用详解
    目录Python函数和代码复用一、函数的定义二、函数的调用三、函数的参数传递1.形式参数与实际参数2.位置传参与关键字传参3.可变对象与不可变对象的参数传递4.个数可变的位置、关键字...
    99+
    2022-11-11
  • 通过JDK源码学习InputStream详解
    概况本文主要给大家介绍了通过JDK源码学习InputStream的相关内容,JDK 给我们提供了很多实用的输入流 xxxInputStream,而 InputStream 是所有字节输入流的抽象。包括 ByteArrayInputStrea...
    99+
    2023-05-30
    inputstream jdk源码 npu
  • python学习之Python count()函数详解
    大家好,依旧是你们的萧萧啊。 Python中的count()函数是一种非常常用的方法,用于统计某个元素在列表、元组或字符串中出现的次数。它的使用非常简单,只需要传入要统计的元素作为参数即可。在本篇博客中,我将详细介绍count()函数的用法...
    99+
    2023-09-29
    学习 python
  • Python学习之迭代器详解
    目录什么是迭代器如何生成迭代器迭代器函数 - iter() 函数 与 next() 函数可迭代的对象生成迭代器迭代器的用法 - 演示案例什么是迭代器 迭代是 python 中访问集合...
    99+
    2022-11-13
  • 详解python学习笔记之解释器
    目录1、python教程1.1 概述1.2 python标准库1.3 python语言参考手册1.4 python包索引1.5 术语对照表2、课前甜点3、python解析器3.1 传...
    99+
    2022-11-13
  • Python学习之日志模块详解
    目录日志的作用日志的等级logging 模块的使用logging 模块演示小案例OK,今天我们来学习一下 python 中的日志模块,日志模块也是我们日后的开发工作中使用率很高的模块...
    99+
    2022-11-13
  • Python学习之循环方法详解
    目录for循环while循环拓展:列表推导式常见的推导式方法循环的继续与退出(continue与break)continue的使用break的使用循环实现九九乘法表什么是循环? &m...
    99+
    2022-11-13
  • Python学习之异常处理详解
    目录什么是异常与异常处理异常的语法捕获通用异常捕获具体异常如何捕获多个异常捕获多个异常 - 方法1捕获多个异常 - 方法2本章节主要学习 python 中的异常处理,来看一下该章节的...
    99+
    2022-11-13
  • Python学习之异常断言详解
    该章节我们来学习 异常的最后一个知识点 - 断言 ,断言是判断一个表达式,在表达式为 False 的时候触发异常。表达式我们可以对号入座,可以是条件语句中的声明,也可以是是 whil...
    99+
    2022-11-13
  • Python学习之包与模块详解
    目录什么是 Python 的包与模块包的身份证如何创建包创建包的小练习包的导入 - import模块的导入 - from…import导入子包及子包函数的调用导入主包及...
    99+
    2022-11-13
  • python源码剖析之PyObject详解
    目录一、Python中的对象1.1 对象机制的基石PyObject二、类型对象2.1 对象的创建2.2 对象的行为2.3 类型的类型三、Python的多态性四、引用计数五、Pytho...
    99+
    2022-11-12
  • Python学习之文件的读取详解
    目录文件读取的模式文件对象的读取方法使用 read() 函数一次性读取文件全部内容使用 readlines() 函数 读取文件内容使用 readline() 函数 逐行读取文件内容m...
    99+
    2022-11-13
  • Python集成学习之Blending算法详解
    目录一、前言二、Blending介绍三、Blending流程图四、案例一、前言 普通机器学习:从训练数据中学习一个假设。 集成方法:试图构建一组假设并将它们组合起来,集成学习是一种机器学习范式,多个学习器被训练来解决...
    99+
    2022-06-02
    Python Blending算法 python算法
  • Python学习之元组的使用详解
    目录元组的创建元组的删除元组部分元素的输出元组的嵌套元组元素的个数计算:len()元组中的元素最大最小值的求解:max(),min()元组中某元素出现的次数:count函数元组中某元...
    99+
    2022-11-11
  • Python学习之随机模块random详解
    目录random.random()random.uniform()random.randint()random.choice()random.sample()random.randr...
    99+
    2022-11-13
  • Python学习之自定义异常详解
    目录自定义抛出异常关键字 - raise演示小案例 - 1演示小案例 - 2自定义异常类总结在上一章我们学习了 异常的三个关键字,分别是try、except 以及 finally。我...
    99+
    2022-11-13
  • elementui源码学习仿写el-link示例详解
    目录正文组件思考组件的需求组件的效果图组件实现分析给link组件加上链接样式给link组件加上鼠标悬浮时下划线通过传参控制是否加上下划线(即:是否加上这个下划线类名)使用v-bind...
    99+
    2022-12-20
    elementui仿写el-link示例 element-ui el-link
  • 详解Spring batch 入门学习教程(附源码)
    Spring batch 是一个开源的批处理框架.执行一系列的任务. 在 spring batch 中 一个job 是由许多 step 组成的。而每一个 step  又是由 READ-PROCESS-WRITE task或者 单个...
    99+
    2023-05-30
    spring batch tc
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作