本文主要从以下几个方面来叙述:
1.PyListObject对象
2.PyListObject对象的创建与维护(包括对象的创建、删除、插入以及设置)
3.PyListObject对象缓冲池 一、PyListObject对象
一、PyListObject对象
首先来看看PyListObject对象的定义:
typedef struct { PyObject_VAR_HEAD //这里面有个ob_size PyObject **ob_item; // 指向元素列表首地址的指针,list[0]==ob_item[0] Py_ssize_t allocated;//指出列表中可容纳的元素的总数 } PyListObject;
PyObject_VAR_HEAD:这个宏定义我们在第一次讲解的时候就已经阐述了。其中有个ob_size变量,这个变量存放着当前PyListObject对象存放的元素的个数.
ob_item:这个二级指针指向了一段内存空间的首地址.
allocated:这个变量存放的是列表中元素的总个数.
对于一个PyListObject对象,一定会有以下关系:
0<= ob_size <= allocated
len(list) == ob_size
ob_item == NULL 意味着ob_size == allocated == 0
二、PyListObject对象的创建与维护(包括对象的创建、删除、插入以及设置)
1.对象的创建
唯一途径----PyList_New,参数size指定了初始化列表的元素个数。
PyObject *PyList_New(Py_ssize_t size){ PyListObject *op; size_t nbytes; if (size < 0) { PyErr_BadInternalCall(); return NULL; } if ((size_t)size > PY_SIZE_MAX / sizeof(PyObject *)) return PyErr_NoMemory(); //[1]内存数量计算,溢出检查 nbytes = size * sizeof(PyObject *); //[2]为PyListObject对象申请空间 if (numfree) { //缓冲池可以用 numfree--; op = free_list[numfree]; _Py_NewReference((PyObject *)op); } else { //缓冲池不用 op = PyObject_GC_New(PyListObject, &PyList_Type); if (op == NULL) return NULL; } //[3]为PyListObject对象中维护的元素列表申请空间 if (size <= 0) op->ob_item = NULL; else { op->ob_item = (PyObject **) PyMem_MALLOC(nbytes); if (op->ob_item == NULL) { Py_DECREF(op); return PyErr_NoMemory(); } memset(op->ob_item, 0, nbytes); } Py_SIZE(op) = size; op->allocated = size; return (PyObject *) op; }