Python源码学习之PyType_Type和PyBaseObject_Type详解
作者:Jakob_Hu 发布时间:2023-08-03 15:50:05
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 */
// ...
};
第2行使用初始化
ob_refcnt
、ob_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_Type
是PyTypeObject
的一个实例。PyType_Type
是类型机制中至关重要的对象,是所有类型的类型,称为元类型。第2行代码处
PyType_Type
将自身的ob_type
字段指向它自己。
>>> type.__class__
<class 'type'>
>>> type.__class__ is type
True
由此,以float为例,可以绘制一个更完善但是并不完全正确的实例对象和类型对象在内存中的关系图,
二. 类型之基—PyBaseObject_Type(object的实体)
上一节中红色标记的语句,并不完全正确是因为思考过程中忽略了object
对象的存在。
object
是另一个特殊的类型,是所有类型的基类。同样可以通过PyFloat_Type
中tp_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为例,
来源:https://blog.csdn.net/Jakob_Hu/article/details/117913750


猜你喜欢
- 一.概述IO 内存是sql server最重要的资源,数据从磁盘加载到内存,再从内存中缓存,输出到应用端,在sql server 内存初探中
- 学Python之前我们先来几个简单的小游戏练练手,这三个小游戏一个比一个复杂,建议新手慢慢来:1.猜拳import random  
- 写在前面的话:此篇还是asp相关的,相信玩ASP的都有这个感觉,当数据有5万多条时-------just like音乐网,要调用最新的10条
- 1. 将Oracle 10g client安装包copy到本地才能安装:2. 双击setup 的到:3. 稍后进入安装界面:4. 选择下一步
- 直接看如下图解1、右击项目,查看提交历史2、选择要回滚的版本,点击回滚3、push回滚的内容:双击该回滚记录,弹出后,检查一下回滚的内容,没
- 代码如下:<% set studentinstance = CreateStudent()&n
- 本文实例讲述了Python文件与文件夹常见基本操作。分享给大家供大家参考,具体如下:1、判断文件(夹)是否存在。os.path.exists
- 前言:在 Web 页面经常会有各种事件发生,事件发生后需要进行一些特定处理,即执行特定的函数或者语句。这就需要对事件进行监听,监听事件的常见
- mro即 method resolution order (方法解释顺序),主要用于在多继承时判断属性的路径(来自于哪个类)。在python
- 1. 什么是Matplotlibmatplotlib是专门用于开发2D图表(包括3D图表),以渐进、交互式方式实现数据可视化。使用pytho
- 本文实例为大家分享了JavaScript实现涂鸦笔的具体代码,供大家参考,具体内容如下1、html部分、css部分1.1 实现一个画框<
- 使用del和drop方法删除DataFrame中的列,使用drop方法一次删除多列数据准备:import pandas as pd 
- 本文实例为大家分享了Python银行系统的具体代码,供大家参考,具体内容如下import timeimport randomimport p
- 在 Golang 中处理浮点数存在着精度问题,而精度问题会带来诸多的麻烦。因此,我们需要使用高精度数来解决这个问题。shopspring/d
- 批量更新mysql更新语句很简单,更新一条数据的某个字段,一般这样写:UPDATE mytable SET myfield = 'v
- 最近在用GAE开发自己的博客程序。虽然GAE的API没有显式的提供操作Cookie的方法,但他现有的架构,使我们有足够的自由来操作Cooki
- 记录一下如何用python爬取app数据,本文以爬取抖音视频app为例。编程工具:pycharmapp抓包工具:mitmproxyapp自动
- isnull在数据库查询中的应用,特别是再语句连接的时候需要用到 比如连接时候,某个字段没有值但是又要左连接到其他表上 就会显示空, isn
- 示例: 创建Table CREATE TABLE [dbo].[xmlTable]( [id] [int] IDENTITY(1,1) NO
- 本文讲述了LINUX下Oracle数据导入导出的方法。分享给大家供大家参考,具体如下:一. 导出工具 exp1. 它是操作系统下一个可执行的