在Python2中,有 PyIntObject 和 PyLongObject 两种整数类型,在Python3中,前者并入后者。本文是Python2 相关的内容。
PyIntObject
整数对象定义在头文件 Include/intobject.h 中,它表示一个(长)整数,且是一个不可变(immutable)对象。
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
和PyObject相比,它只多了一个 ob_ival 成员,用来封装C中的long类型。
PyIntObject 的类型值是: PyInt_Type,定义在 Objects/intobject.c 中
PyInt_Type
定义在 Objects/intobject.cpp 中,且在 Include/intobject.h 中用 extern 进行声明。
PyAPI_DATA(PyTypeObject) PyInt_Type;
PyTypeObject PyInt_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"int",
sizeof(PyIntObject),
...
(cmpfunc)int_compare, /* tp_compare */
(reprfunc)int_to_decimal_string, /* tp_repr */
&int_as_number, /* tp_as_number */
...
(reprfunc)int_to_decimal_string, /* tp_str */
...
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_INT_SUBCLASS, /* tp_flags */
int_doc, /* tp_doc */
...
int_new, /* tp_new */
(freefunc)int_free, /* tp_free */
};
宏 PyVarObject_HEAD_INIT 定义在 Include/object.h 中,用来初始化PyVarObject的3个成员(引用计数始终初始化为1)
PyNumberMethods
&int_as_number 是指向结构体PyNumberMethods实例的指针,该结构体的成员是函数指针:
static PyNumberMethods int_as_number = {
(binaryfunc)int_add, /*nb_add*/
(binaryfunc)int_sub, /*nb_subtract*/
(binaryfunc)int_mul, /*nb_multiply*/
(binaryfunc)int_classic_div, /*nb_divide*/
(binaryfunc)int_mod, /*nb_remainder*/
(binaryfunc)int_divmod, /*nb_divmod*/
(ternaryfunc)int_pow, /*nb_power*/
(unaryfunc)int_neg, /*nb_negative*/
...
这些函数实现了整数的四则运算等操作。比如加法
static PyObject *
int_add(PyIntObject *v, PyIntObject *w)
{
register long a, b, x;
CONVERT_TO_LONG(v, a);
CONVERT_TO_LONG(w, b);
/* casts in the line below avoid undefined behaviour on overflow */
x = (long)((unsigned long)a + b);
if ((x^a) >= 0 || (x^b) >= 0)
return PyInt_FromLong(x);
return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
}
返回结果是通过PyInt_FromLong创建的新对象。如果溢出的话,则调用PyLong_Type的加法函数。
创建
为了提高效率,某个范围内的小整数进行了缓存(是该称作缓存么?)。
小整数
缓存在一个静态的 small_ints 的数组中:
需要缓存的数据范围由两个宏进行指定(所以修改的话需要重新编译python)
#define NSMALLPOSINTS 257
#define NSMALLNEGINTS 5
/* References to small integers are saved in this array so that they
can be shared.
The integers that are saved are those in the range
-NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
大整数
大整数存放在PyIntBlock的一个单向链表中,每一个PyIntBlock项中可以存放若干个(N_INTOBJECTS)整数。
/*
block_list is a singly-linked list of all PyIntBlocks ever allocated,
linked via their next members. PyIntBlocks are never returned to the
system before shutdown (PyInt_Fini).
free_list is a singly-linked list of available PyIntObjects, linked
via abuse of their ob_type members.
*/
#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
#define N_INTOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))
struct _intblock {
struct _intblock *next;
PyIntObject objects[N_INTOBJECTS];
};
typedef struct _intblock PyIntBlock;
static PyIntBlock *block_list = NULL;
static PyIntObject *free_list = NULL;
此处两个静态的指针,block_list 和 free_list 分别指向整数块(IntBlock)链表和空闲空间(IntObject)链表的头部。
有问题是不?PyIntBlock很容易看出是一个链表的节点,可是PyIntObject如何能是链表的节点呢?
它只有3个成员:
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
long ob_ival;
哦,原来它使用的 ob_type 来存放下一个节点指针!!
这样以来,当新建整数时,首先判断是否是小整数,是的话,直接使用缓存中的小整数,反之,看看整数块有没有空闲的空间,有则使用,无则申请新的整数块。
PyObject *
PyInt_FromLong(long ival)
{
register PyIntObject *v;
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
v = small_ints[ival + NSMALLNEGINTS];
Py_INCREF(v);
#ifdef COUNT_ALLOCS
if (ival >= 0)
quick_int_allocs++;
else
quick_neg_int_allocs++;
#endif
return (PyObject *) v;
}
#endif
if (free_list == NULL) {
if ((free_list = fill_free_list()) == NULL)
return NULL;
}
/* Inline PyObject_New */
v = free_list;
free_list = (PyIntObject *)Py_TYPE(v);
PyObject_INIT(v, &PyInt_Type);
v->ob_ival = ival;
return (PyObject *) v;
}
PyInt_From*
整数的创建:
-
从C的整数类型创建Python的整数对象
-
从字符串创建Python的整数对象
PyObject * PyInt_FromLong(long ival)
PyObject * PyInt_FromSize_t(size_t ival)
PyObject * PyInt_FromSsize_t(Py_ssize_t ival)
PyObject * PyInt_FromString(char *s, char **pend, int base)
PyObject * PyInt_FromUnicode(Py_UNICODE *s, Py_ssize_t length, int base)
参考
分享到:
相关推荐
Python源码剖析 首页 Python总体架构 对象机制 字符串对象PyStringObject(1) 字符串对象PyStringObject(2) 字符串对象PyStringObject(3) 整数对象PyIntObject(1) 整数对象PyIntObject(2) 整数对象PyIntObject(3) ...
Python BBS论坛源码 Python源码Python BBS论坛源码 Python源码Python BBS论坛源码 Python源码Python BBS论坛源码 Python源码Python BBS论坛源码 Python源码Python BBS论坛源码 Python源码Python BBS论坛源码 Python...
Python源码剖析.pdf
Python Excel数据分析 Python源码Python Excel数据分析 Python源码Python Excel数据分析 Python源码Python Excel数据分析 Python源码Python Excel数据分析 Python源码Python Excel数据分析 Python源码Python Excel...
圣诞树代码编程python源码附赠30个Python应用源码圣诞树代码编程python源码附赠30个Python应用源码圣诞树代码编程python源码附赠30个Python应用源码圣诞树代码编程python源码附赠30个Python应用源码圣诞树代码编程...
玫瑰花python源码.zip玫瑰花python源码.zip玫瑰花python源码.zip玫瑰花python源码.zip玫瑰花python源码.zip玫瑰花python源码.zip玫瑰花python源码.zip玫瑰花python源码.zip玫瑰花python源码.zip玫瑰花python源码.zip...
Python源码学习笔记
Python 笔记源码——内含python后端&机器学习等.zip Python 笔记源码——内含python后端&机器学习等.zip Python 笔记源码——内含python后端&机器学习等.zip Python 笔记源码——内含python后端&机器学习等.zip ...
Python 游戏源码 - 飞鸟小游戏 Python源码Python 游戏源码 - 飞鸟小游戏 Python源码Python 游戏源码 - 飞鸟小游戏 Python源码Python 游戏源码 - 飞鸟小游戏 Python源码Python 游戏源码 - 飞鸟小游戏 Python源码...
Python 如何自动对多个Word文档提取目录 Python源码Python 如何自动对多个Word文档提取目录 Python源码Python 如何自动对多个Word文档提取目录 Python源码Python 如何自动对多个Word文档提取目录 Python源码Python ...
Golang和Python源码学习
Python 读取Excel、文本、CSV等不同类型数据 Python源码Python 读取Excel、文本、CSV等不同类型数据 Python源码Python 读取Excel、文本、CSV等不同类型数据 Python源码Python 读取Excel、文本、CSV等不同类型数据 ...
python源码剖析笔记 python源码剖析笔记 python源码剖析笔记
Python 如何实现在PyQt5窗口中弹出等待提示框 Python源码Python 如何实现在PyQt5窗口中弹出等待提示框 Python源码Python 如何实现在PyQt5窗口中弹出等待提示框 Python源码Python 如何实现在PyQt5窗口中弹出等待提示...
Python 重复数据处理(df.drop_duplicates方法)Python源码Python 重复数据处理(df.drop_duplicates方法)Python源码Python 重复数据处理(df.drop_duplicates方法)Python源码Python 重复数据处理(df.drop_...
Python 商城源码 Python源码Python 商城源码 Python源码Python 商城源码 Python源码Python 商城源码 Python源码Python 商城源码 Python源码Python 商城源码 Python源码Python 商城源码 Python源码Python 商城源码 ...
基于机器学习的电影推荐系统python源码+数据集(下载即用).zip基于机器学习的电影推荐系统python源码+数据集(下载即用).zip基于机器学习的电影推荐系统python源码+数据集(下载即用).zip基于机器学习的电影推荐系统...
python 源码 三剑客“python编程从入门到实践、python极客编程、python编程快速上手”。python 源码 三剑客“python编程从入门到实践、python极客编程、python编程快速上手”python 源码 三剑客“python编程从...