官术网_书友最值得收藏!

3.1.1 序列對象解析

Python提供的列表的抽象對象為PyListObject,即List對象。List對象是一個變長對象,在運行時動態調整其所維護的內存和元素,并且支持插入、刪除等操作。

PyListObject對象源碼(Include/listobject.h)結構如下:


// Include/listobject.h
typedef struct {
    PyObject_VAR_HEAD       // 變量頭部信息 
    
    PyObject **ob_item;     // 元素指向具體值

    Py_ssize_t allocated;   // 當前空間
} PyListObject;

結合可變對象的源碼(Include/object.h)如下:


// Include/object.h

typedef struct _object {
    _PyObject_HEAD_EXTRA            // 雙向鏈表 垃圾回收 需要用到
    Py_ssize_t ob_refcnt;           // 引用計數
    struct _typeobject *ob_type;    // 指向類型對象的指針,決定了對象的類型
} PyObject;

typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;

上述源碼中,ob_size和allocated都和PyListObject對象的內存管理有關。ob_size表示列表實際擁有的元素數量,allocated表示實際申請的內存空間,比如列表A實際申請了5個元素的空間,但此時A只包含2個元素,則ob_size為2,allocated為5。

生成新的List對象時,首先檢查緩沖池是否有List對象,若沒有,則新生成一個List對象。新建的List對象默認維護80個PyListObject對象,源碼(Object/Listobject.c)如下:


// Object/listobject.c

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

每次對序列對象添加元素時,都會調整列表的大小。在調整列表大小后,如果傳入的負值索引比列表長度還大,則傳入值設置在0位;如果傳入的正值索引比列表長度還大,則傳入值設置為最后一位,并將大于索引值的元素往后移動一位。這就是序列插入的大致過程。

這里對序列的源碼做一些簡單講解,對序列源碼感興趣的讀者可以重點查看Include/listobject.h和Object/listobject.c這兩個文件。序列的創建、插入、刪除、調整等的源碼實現都在Object/listobject.c文件中。

主站蜘蛛池模板: 出国| 香河县| 绥德县| 宁强县| 漳浦县| 革吉县| 西青区| 全南县| 宜都市| 永德县| 阿荣旗| 铜陵市| 顺昌县| 泰顺县| 东明县| 河池市| 贺州市| 中山市| 阿城市| 姜堰市| 砚山县| 寿宁县| 和硕县| 会东县| 临夏市| 屯门区| 云和县| 东乡族自治县| 南通市| 平泉县| 阆中市| 汾阳市| 泸定县| 遵义市| 平谷区| 璧山县| 嫩江县| 锦屏县| 嘉兴市| 横峰县| 南丹县|