Python int对象的实现
Python内部关于int对象的实现在我之前的两篇文章中其实已经简单的介绍过,本文会前面的基础上更加深入的分析int对象的内部实现,以及Python对int对象进行优化而采用的缓存技术等等.首先还是来看看int对象在C层面的一个数据结构吧.
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
Include/intobject.h
PyObject_HEAD是一个宏,这在前面的几篇文章中都详细分析过,所以对于int对象来说最重要的莫过于ob_ival
成员了,这个成员用来存放实际存储的数据.有了这个基础我们就可以在Python源码中开始漫游了.先来看看int对象做了哪些初始化动作吧.
int对象的初始化
int
_PyInt_Init(void)
{
PyIntObject *v;
int ival;
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++) {
if (!free_list && (free_list = fill_free_list()) == NULL)
return 0;
/* PyObject_New is inlined */
v = free_list;
free_list = (PyIntObject *)Py_TYPE(v);
PyObject_INIT(v, &PyInt_Type);
v->ob_ival = ival;
small_ints[ival + NSMALLNEGINTS] = v;
}
#endif
return 1;
}
Object/intobject.c
这段初始化代码信息量很大,包含了本文即将分析的小整数对象的缓存优化,还有大整数对象池等知识点.这段初始化代码做了两件事,第一件事就是创建大整数对象池,第二件事就是小整数对象的缓存的初始化.具体细节后面分析到相关知识点的时候再具体分析.这里我们重点看一下PyObject_INIT
,这是一个宏
专门用于初始化类型对象的.在上面的初始化代码中v是一个PyIntObject
类型,但是还没有进行初始化.通过PyObject_INIT
宏.将PyIntObject
对象和这个对象对应的类型PyInt_Type
关联起来.这也是我在前面几篇文章中提到的,对象会在初始化的时候固定其类型.PyInt_Type
是一个专门为int对象进行定制的一个PyTypeObject(如果你忘了这个对象是干什么的,请看我之前的文章)对象.
下面是PyObject_INIT
宏的具体实现:
#define PyObject_INIT(op, typeobj) \
( Py_TYPE(op) = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )
Include/objimpl.h
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
Include/object.h
PyObject_INIT
的实现很简单,就是把PyInt_Type
和PyIntObject
的ob_type
成员关联起来.这样就完成了PyIntObject
对象的初始化了,然后再增加引用计数.到此初始化就结束了,说完了初始化,该说说如何创建一个int对象了吧.
int对象的构造
看一下相关的头文件,发现Python居然提供了这么多的构造函数,可以从字符串,UNICODE,long,size_t,Py_ssize_t等类型来构造一个PyIntObject对象.