2022年Python源码剖析 .pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《2022年Python源码剖析 .pdf》由会员分享,可在线阅读,更多相关《2022年Python源码剖析 .pdf(10页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、中清龙图教育,全球游戏50 强教育品牌第 1 页 共 10 页Python源码剖析对象机制1. 对象在 Python的世界中,一切都是对象,一个整数是一个对象,一个字符串也是一个对象,更为奇妙的是,类型也是一个对象,整数类型是一个对象,字符串类型也是一个对象。从1980 年 Guido 在那个圣诞节揭开 Python世界的大幕开始,一直到现在,Python 经历了一次一次的升级, 但是其实现语言一直都是ANSI C。我们知道, C 并不是一个面向对象的语言,那么在Python中,它的对象机制是如何实现的呢?对 于人的思维来说, 对象是一个比较形象的概念, 而对于计算机来说, 对象实际上是一个抽
2、象的概念。计算机并不能理解这是一个整数,那是一个字符串,对于计算机来说,它所知道的一切都是字节。通常的说法是,对象是数据以及基于这些数据的操作的集合。 在计算机上, 一个对象实际上就是一片被分配的内存空间,这些内存可能是连续的,也有可能是离散的,这都不重要,重要的是这片内存在更高的层次上可以作为一个整体来考虑,这个整体就是一个对象。 在这片内存中,存储着一系列的数据以及可以对这些数据进行修改或读取的一系列操作的代码。在 Python中,对象就是在堆上申请的结构体,对象不能是被静态初始化的,并且也不能是在栈空间上生存的。唯一的例外就是类型对象 (type object),Python中所有的类型
3、对象都是被静态初始化的。在 Python中, 一个对象一旦被创建,它在内存中的大小就是不变的了。这就意味着那些需要容纳可变长度数据的对象只能在对象内维护一个指向一个可变大小的内存区域的指针。为什么要设定这样一条特殊的规则呢,因为遵循这样的规则可以使通过指针维护对象的工作变得非常的简单。因为一旦允许对象的大小可在运行期改变,我们可以考虑如下的情形。在内存中有对象A,并且其后紧跟着对象 B。如果运行期某个时刻, A 的大小增大了,这意味着必须将整个A 移动到内存中的其他位置,否则A 增大的部分将覆盖原本属于B 的数据。一旦将 A 移动到内存中的其他位置,那么所有指向A 的指针必须立即得到更新,光是
4、想一想,就知道这样的工作是多么的恐怖。在 Python中,所有的东西都是对象,而所有的对象都拥有一些相同的内容,这些内容在 PyObject中定义, PyObject是整个 Python对象机制的核心。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 10 页 - - - - - - - - - 中清龙图教育,全球游戏50 强教育品牌第 2 页 共 10 页object.h typedefstruct_objectPyObject_HEADPyObject;实际上,PyOb
5、ject 是 Python中不包含可变长度数据的对象的基石,而对于包含可变长度数据的对象,它的基石是PyVarObject:object.h typedefstructPyObject_VAR_HEADPyVarObject;这两个结构体构成了Python 对象机制的核心基石,从代码中我们可以看到,Python的对象的秘密都隐藏在PyObject_HEAD 与 PyObject_VAR_HEAD 中。object.h #ifdef Py_TRACE_REFS/* Define pointers to support a doubly-linked list of all live heap o
6、bjects. */struct_object* _ob_next; struct_object* _ob_prev;#define _PyObject_EXTRA_INIT 0, 0,#else#define _PyObject_HEAD_EXTRA#define _PyObject_EXTRA_INIT#endif/* PyObject_HEAD defines the initial segment of every PyObject. */_PyObject_HEAD_EXTRA intob_refcnt; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - -
7、- - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 10 页 - - - - - - - - - 中清龙图教育,全球游戏50 强教育品牌第 3 页 共 10 页struct_typeobject* ob_type;PyObject_HEAD intob_size;/* Number of items in variable part */在 PyObject_HEAD 中定义了每一个Python 对象都必须有的内容,这些内容将出现在每一个 Python 对象所占有的内存的最开始的字节中,从PyObject_VAR_HEAD 的定义可以看出, 即使对于拥
8、有可变大小数据的对象,其最开始的字节也含有相同的内容,这就是说,在Python中,每一个对象都拥有相同的对象头部。这就使得在Python中,对对象的引用变得非常的统一,我们只需要用一个 PyObject *就可以引用任意的一个对象,而不论该对象实际是一个什么对象。在 PyObject_HEAD 的定义中,我们注意到有一个ob_refcnt的整形变量,这个变量的作用是实现引用计数机制。对于某一个对象A,当有一个新的 PyObject *引用该对象时, A 的引用计数应该增加;而当这个PyObject *被删除时, A 的引用计数应该减少。当A 的引用计数减少到0 时,A 就可以从堆上被删除,以释
9、放出内存供别的对象使用。在 PyObject_HEAD 中,我们注意到ob_type是一个指向 _typeobject结构体的指针,那么这个结构体是一个什么东西呢?实际上这个结构体也是一个对象,它是用来指定一个对象类型的类型对象。这个类型对象我们将在后边详细地考察。现在我们看到了,在Python 中实际上对象机制的核心非常的简单,一个是引用计数,一个就是类型。而对于拥有可变长度数据的对象,这样的对象通常都是容器,我们可以在PyObject_VAR_HEAD 中看到 ob_size这个变量,这个变量实际上就是指明了该对象中一共包含了多少个元素。注意,ob_size指明的是元素的个数,而不是字节的
10、数目。比如对于Python 中最常用的 list,它就是一个 PyVarObject 对象,如果某一时刻,这个list 中有 5 个元素,那么 PyVarObject.ob_size的值就是 5。2. 类型对象在上面的描述中,我们看到了Python中所有对象的对象头的定义。所以,当内存中存在某一个Python 的 对象时,该对象的开始的几个字节的含义一定会符合我们的预期。但是,当我们把眼光沿着时间轴上溯,就会发现一个问题。当在内存中分配空间, 创建对象的时候,毫无疑问地, 必须要知道申请多大的空间。显然,这不会是一个定值,因为对于不同的对象,需要不同的空间,一个整数对名师资料总结 - - -精
11、品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 10 页 - - - - - - - - - 中清龙图教育,全球游戏50 强教育品牌第 4 页 共 10 页象和一个字符串对象所需的空间肯定不同。那么,对象所需的内存空间的大小的信息到底在哪里呢?在对象头中显然没有这样的信息。实际上,内存空间大小这样的对象的元信息是与对象所属类型密切相关的,因此它一定会出现在与对象所对应的类型对象中。现在我们可以来详细考察一下类型对象 _typeobject:object.h typedefstruct_typeob
12、jectPyObject_VAR_HEADchar* tp_name;/* For printing, in format . */inttp_basicsize, tp_itemsize;/* For allocation */* Methods to implement standard operations */destructortp_dealloc;printfunctp_print;/* More standard operations (here for binary compatibility) */hashfunctp_hash;ternaryfunctp_call;PyTy
13、peObject;在_typeobject的定义中包含了许多的信息,主要可以分为四类:1类型名, tp_name ,主要是 Python内部以及调试的时候使用;2创建该类型对象是分配内存空间的大小的信息,即tp_basicsize和tp_itemsize;3与该类型对象相关联的操作信息,比如hashfunc,tp_hash就指明对于该类型的对象,如何生成其hash值。在 Object.h 中可以看到, hashfunc实际上是一个函数指针: typedef long (*hashfunc)(PyObject *); 在_typeobject中,包含了大量的函数指针, 这些函数指针将用来指定某个
14、类型的操作信息。这些操作主要分为标准操作 (dealloc, print, compare) ,标准操作族 (numbers, sequences, mappings),以及其他操作( hash, buffer, call)。4我们在下边将要描述的类型的类型信息。有趣的是我们在 _typeobject的头部发现了 PyObject_VAR_HEAD ,这意味着类型实际上也是一个对象。我们知道在Python 中,每一个对象都是对应一种类型的,那么一个有趣的问题就出现了, 类型对象的类型是什么呢?这个问题听上名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - -
15、- - - - - - 名师精心整理 - - - - - - - 第 4 页,共 10 页 - - - - - - - - - 中清龙图教育,全球游戏50 强教育品牌第 5 页 共 10 页去很绕口, 实际上确非常重要, 对于其他的对象, 可以通过与其关联的类型对象确定其类型,那么通过什么来确定一个对象是类型对象呢?答案就是PyType_Type:typeobject.c PyTypeObjectPyType_Type= PyObject_HEAD_INIT(& PyType_Type)0, /* ob_size */type, /* tp_name */sizeof( PyHeapTypeO
16、bject) , /* tp_basicsize */sizeof( PyMemberDef) , /* tp_itemsize */PyObject_GC_Del, /* tp_free */( inquiry) type_is_gc, /* tp_is_gc */ ;前面提到,在 Python中,每一个对象它的开始部分都是一样的。每一个对象都将自己的引用计数, 类型信息保存在开始的部分中。 为了方便对这部分内存的初始化, Python中提供了几个有用的宏:object.h #ifdef Py_TRACE_REFS#define _PyObject_EXTRA_INIT 0, 0,#else
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年Python源码剖析 2022 Python 源码 剖析
![提示](https://www.deliwenku.com/images/bang_tan.gif)
限制150内