0. 参考资料
本文参考资料如下:
- B站 CPython源码分析: P4 4.long对象解析和Hook
1. 整数类型
首先我们要有两个知识点:
- 在cpython的上层(也就是python)中看到的int型,在cpython中是以Long类型来实现的。
- 在cpython中对于整数将分为大整数与小整数两种情况进行处理
1.1. 整数对象的头文件定义
我们先看一下cpython中关于整数对象的头文件:
下面的代码摘录自: cpython源码3.8分支的
Include/longobject.h
文件中:
/* Long (arbitrary precision) integer object interface */
typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */
PyAPI_DATA(PyTypeObject) PyLong_Type;
在上面的代码中说明了_longobject
的定义在 Include/longintrepr.h
文件,如下:
/* Long integer representation.
The absolute value of a number is equal to
SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
Negative numbers are represented with ob_size < 0;
zero is represented by ob_size == 0.
In a normalized number, ob_digit[abs(ob_size)-1] (the most significant
digit) is never zero. Also, in all cases, for all valid i,
0 <= ob_digit[i] <= MASK.
The allocation function takes care of allocating extra memory
so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available.
CAUTION: Generic code manipulating subtypes of PyVarObject has to
aware that ints abuse ob_size's sign bit.
*/
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
解释:
PyObject_VAR_HEAD
极重要,它的介绍,可以参考我单独写的《cpython中的PyObject等对象入门》。digit ob_digit[1];
: 上面的注释有详细的解释,但是先不用深入理解。 但需要知道如下信息:- 它是1维数组,默认情况下数组中只有1个元素
ob_digit
数组的长度与ob_size
有着密切的关系,而ob_size
的定义在PyObject_VAR_HEAD
中, 表示的是可变长度对象的元素个数。
1.2. 整数对象的c代码实现
接着看一下整数对象的C代码的实现:
下面的代码摘录自: cpython源码3.8分支的
Objects/longobject.c
文件中:
PyTypeObject PyLong_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"int", /* tp_name */
offsetof(PyLongObject, ob_digit), /* tp_basicsize */
sizeof(digit), /* tp_itemsize */
0,