该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
具体的构造方法 PyInt_FromLong
这个方法的定义
PyObject *
PyInt_FromLong(long ival)
{
register PyIntObject *v;
/* MARK: 如果, 值在小整数范围内, 直接从小整数对象池获取得到对象 */
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
if (-NSMALLNEGINTS ival & ival NSMALLPOSINTS) {
/* MARK: small_ints是什么后面说 */
v = small_ints[ival + NSMALLNEGINTS];
// 引用+1
Py_INCREF(v);
/* 这里先忽略, 计数 */
#ifdef COUNT_ALLOCS
if (ival >= 0)
quick_int_allocs++;
else
quick_neg_int_allocs++;
#endif
// 返回
return (PyObject *) v;
}
#endif
// 如果free_list还不存在, 或者满了
if (free_list == NULL) {
// 新建一块PyIntBlock, 并将空闲空间链表头部地址给free_list
if ((free_list = fill_free_list()) == NULL)
// 如果失败, 返回
return NULL;
}
// 从free_list分出一个位置存放新的整数
/* Inline PyObject_New */
// 使用单向链表头位置
v = free_list;
// free_list指向单向链表下一个位置
free_list = (PyIntObject *)Py_TYPE(v);
// 初始化对象, 类型为PyInt_type, 值为ival
PyObject_INIT(v, &PyInt_Type);
v->ob_ival = ival;
// 返回
return (PyObject *) v;
}
注意这里的Py_TYPE()方法, 在我们第一篇文章里面有提到, 不知道的回去复习下对象的数据结构
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
简而言之:
1. 先判断数值是否是小整数, 是的话从小整数对象池里面直接返回
(这个池固定大小, 下一点讲)
2. 如果不是, 从通用整数对象池里面取一个, 初始化返回
(如果这时候通用整数对象池还不存在或者已经满了, 新建一个池加入维护. 通用整数对象池后面讲)