- Python進階編程:編寫更高效、優雅的Python代碼
- 劉宇宙 謝東 劉艷
- 548字
- 2021-04-30 12:39:42
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文件中。
推薦閱讀
- Boost程序庫完全開發指南:深入C++”準”標準庫(第5版)
- 大學計算機基礎(第三版)
- 騰訊iOS測試實踐
- PostgreSQL Cookbook
- Python深度學習
- Java開發入行真功夫
- C語言程序設計
- 深度強化學習算法與實踐:基于PyTorch的實現
- MySQL數據庫管理與開發實踐教程 (清華電腦學堂)
- 算法訓練營:提高篇(全彩版)
- Apache Camel Developer's Cookbook
- Learning JavaScript Data Structures and Algorithms(Second Edition)
- ASP.NET求職寶典
- Android編程權威指南(第4版)
- jQuery Mobile Web Development Essentials(Second Edition)