PyIntObject就是python中int在虚拟机中的实体,我们来看一下它长什么样。
// file: intobject.h
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
可以看到,其实PyIntObject的结构很简单,就是在PyObject的基础上加了一个long。而这个ob_ival就是这个int对象的具体值。
那么这个int对象是如何被初始化的呢?是不是ob_ival=1就是完成了呢?显然不是的。因为PyObject_HEAD这个宏展开后还有许多内容需要被初始化。我们直接查看intobject.c中的其中一个初始化方法PyInt_FromLong。
一旦有宏穿插再代码里就会显得不甚美观,但用点耐心发现也不是这么难读。我把理解直接写在注释里,方便说明。
// 用一个long值初始化一个PyIntObject。
// 可以理解为在python命令行中敲一个1,python会先初始化一个值为1的PyIntObject
PyObject * PyInt_FromLong(long ival)
{
// register 关键字是告诉编译器这个变量尽可能存放在寄存器中,因为会很常被用到,
// 并不是什么类型都可以被register修饰哦。
// 首先声明一个PyIntObject* 指针v
register PyIntObject *v;
// 如果有定义小整形的范围,那么从小整形池中去找已经初始化过的对象。
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
v = small_ints[ival + NSMALLNEGINTS]; // 找到该对象的指针并赋值给v
Py_INCREF(v); // 增加其引用计数
return (PyObject *) v; // 直接返回
}
#endif
// free_list是那些被创建过的对象,但后来它要被销毁了,但如果
// 一个PyIntObject不用了就要被销毁,创建了又要重新分配内存,
// 这相当不划算,于是搞了个空闲PyIntObject链表,free_list一直指向链表的头部
if (free_list == NULL) {
// if里面表示,如果free_list是空,那么就是链表还没初始化,,那么就给它
// 初始化一下