简介:
在家过了个春节快不知道自己是干啥的了:),今天收拾一下心情继续读一下python的源码。这一节打算探究一下Python中列表是如何实现的。
1.Python列表创建
首先来到listobject.c文件找到今天的主角PyListObject,像之前一样将它拆解开来。
typedef struct {
PyObject ob_base; // 在整数节已经介绍过,主要包含引用计数和类型
Py_ssize_t ob_size;// 用于指明列表中包含几个元素
PyObject **ob_item;
Py_ssize_t allocated;
} PyListObject;
这样拆解之后我们会看到ob_item,allocated还不能很好的确定它们代表什么,那么我接着往下看列表是如何新建的,这里找到新建的方法PyList_New:
// 这里为了方便理解我把源码简化了一下
PyObject *
PyList_New(Py_ssize_t size)
{
PyListObject *op;
if (size < 0) { // 检查列表元素个数不小于0
PyErr_BadInternalCall();
return NULL;
}
if (numfree) { // 检查是否有缓存可用
numfree--;
op = free_list[numfree];
_Py_NewReference((PyObject *)op);
} else {
op = PyObject_GC_New(PyListObject, &PyList_Type);
if (op == NULL)
return NULL;
}
// 下面就是开辟内存新建一个列表
if (size <= 0)
op->ob_item = NULL;
else {
op->ob_item = (PyObject **) PyMem_Calloc(size, sizeof(PyObject *));
if (op->ob_item == NULL) { // 内存开辟失败
Py_DECREF(op);
return PyErr_NoMemory();
}
}
// 下面为ob_size和allocated赋初始值
Py_SIZE(op) = size;
op->allocated = size;
_PyObject_GC_TRACK(op);
return (PyObject *) op;
}
这样我们就可以看出allocated跟ob_size一致,ob_item指向列表内存空间。
2.Python列表填充元素
上面新建了列表元素全是NULL,接下来通过PyList_SetItem为列表填充值。
int PyList_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem)
{
PyObject **p;
if (!PyList_Check(op)) { // 检查op类型
Py_XDECREF(newitem);
PyErr_BadInternalCall();
return -1;
}
if (i < 0 || i >= Py_SIZE(op)) { // 检查索引是否越界
Py_XDECREF(newitem);
PyErr_SetString(PyExc_IndexError,
"list assignment index out of range");
return -1;
}
// 下面对指定元素赋值
p = ((PyListObject *)op) -> ob_item + i;
Py_XSETREF(*p, newitem);
return 0;
}
设置完值必然还会有取值方法PyList_GetItem
PyObject *
PyList_GetItem(PyObject *op, Py_ssize_t i)
{
if (!PyList_Check(op)) {
PyErr_BadInternalCall();
return NULL;
}
if (i < 0 || i >= Py_SIZE(op)) {
if (indexerr == NULL) {
indexerr = PyUnicode_FromString(
"list index out of range");
if (indexerr == NULL)
return NULL;
}
PyErr_SetObject(PyExc_IndexError, indexerr);
return NULL;
}
return ((PyListObject *)op) -> ob_item[i];
}
3.图示
下面就针对上述结构做一个简单的图示
从这里不难看出,其实这时候开辟的空间均只包含指针,也能理解了为什么Python中为什么列表是可变类型的。
到这里先简单了解一下Python列表的创建,后面再一一查看对列表的操作。
欢迎关注wx公众号:python web小栈,共同探讨学习