python底层设计:列表对象设计

 

目录

1.初识PyListObject

2.PyListObject对象的创建和维护

2.1创建对象

2.2设置元素

2.3 内存分配方式

2.4.常见操作原理:

3.PyListObject对象缓冲池


1.初识PyListObject

    python里的列表不是书上基于链表的列表,而是基于可变长度的数组。PyListObject对象可以有效支持元素插入添加删除等操作,它的定义为:

typedef struct {
    PyObject_VAR_HEAD

    PyObject **ob_item;
    Py_ssize_t allocated;
} PyListObject;

     ob_item指针指向元素列表所在内存块首地址,而allocated中则维护了当前列表中可容纳的元素总数。我们知道PyObject_VAR_HEAD中有一个ob_size,它维护的是当前列表中已容纳的元素数量

 

2.PyListObject对象的创建和维护

2.1创建对象


PyObject *PyList_New(Py_ssize_t size)
{
    PyListObject *op;
    static int initialized = 0;
    if (!initialized) {
        Py_AtExit(show_alloc);
        initialized = 1;
    }
#endif

    if (size < 0) {
        PyErr_BadInternalCall();
        return NULL;
    }
    if (numfree) {
    缓冲池可用
        numfree--;
        op = free_list[numfree];
        _Py_NewReference((PyObject *)op);
        count_reuse++;
    } else {
    缓冲池不可用
        op = PyObject_GC_New(PyListObject, &PyList_Type);
        if (op == NULL)
            return NULL;
        count_alloc++;
    }
    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();
        }
    }
    Py_SIZE(op) = size;
    op->allocated = size;
    _PyObject_GC_TRACK(op);
    return (PyObject *) op;
}

    从上面的创建动作我们可以看出,列表对象实际上分为两部分,一是PyListObject对象本身,二是PyListObject对象维护的元素列表,这是两块分离的内存,通过ob_item建立联系。

     另外,创建新的PyListObject对象时我们可以看到非常熟悉的缓冲池技术。在创建PyListObject时,会先检查缓冲池free_list中是否有可用的对象。如果有,则直接使用,否则通过PyObject_GC_New咋系统堆中申请内存,创建新的PyListObject。

    在python3.7.5中,默认情况下,free_list最多只有80个PyListObject对象。

#define PyList_MAXFREELIST 80
#endif
static PyListObject *free_list[PyList_MAXFREELIST];
static int numfree = 0;

 

2.2设置元素

   假设我们创建一个包含6个元素的PyListObject,它的内存图如下:

     注意创建一个list时列表元素不可能是null,这里只是为了演示元素变化。假设我们在第4个位置添加100,添加过程如下:

int
PyList_SetItem(PyObject *op, Py_ssize_t i,
               PyObject *newitem)
{
    PyObject **p;
    if (!PyList_Check(op)) {
        Py_XDECREF(newitem);
        PyErr_BadInternalCall();
        return -1;
    }
    【1】索引检查
    if (i < 0 || i >
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值