list對(duì)象定義:
typedef struct {
PyObject_VAR_HEAD
PyObject **ob_item;
Py_ssize_t allocated;
} PyListObject;
list對(duì)象是變長(zhǎng)對(duì)象,所以有變長(zhǎng)對(duì)象頭.
ob_item數(shù)組為真正的存儲(chǔ)容器铝噩,用來存儲(chǔ)PyObject對(duì)象指針赘那。
ob_size表示list長(zhǎng)度评雌。
allocated表示list已分配了多少存儲(chǔ)空間。
list創(chuàng)建與銷毀
list的創(chuàng)建分兩步螟加。
- 創(chuàng)建list對(duì)象本身徘溢。
- 為ob_item分配內(nèi)存。
list的銷毀也分兩步捆探。 - 回收ob_item的內(nèi)存然爆。
- 銷毀list對(duì)象本身。
這樣的對(duì)象創(chuàng)建和銷毀方案是為對(duì)象池(free_lists)服務(wù)的黍图。
在創(chuàng)建list階段施蜜,Python會(huì)查看free_lists中是否有緩存對(duì)象。若有雌隅,則直接從free_lists取出翻默。若沒有,則從堆上分配list對(duì)象內(nèi)存恰起。
在銷毀list階段修械,若緩存list數(shù)(num_free_lists)小于最大可緩存數(shù)(MAXFREELISTS ),則將list對(duì)象緩存到free_lists備用检盼。若超過了num_free_lists肯污,則直接釋放對(duì)象內(nèi)存。
賦值操作
設(shè)置元素操作可以理解為list[i] = obj吨枉。
插入操作
插入元素操作:實(shí)質(zhì)是函數(shù)ins1的包裝蹦渣。ins1函數(shù)的關(guān)鍵操作是,先通過list_resize(下面細(xì)說)調(diào)整list長(zhǎng)度貌亭,然后確定插入點(diǎn)柬唯。由于Python list的索引可以為負(fù)數(shù)(即末尾元素索引為-1),所以索引值小于0時(shí)得加上長(zhǎng)度得到C數(shù)組的索引圃庭。接著將插入點(diǎn)后的元素向后搬運(yùn)锄奢,在插入點(diǎn)寫入對(duì)象失晴。從此可以看出list就是C里數(shù)組的概念。
list_resize函數(shù):int list_resize(PyListObject *self, Py_ssize_t newsize)
如果allocated / 2 <= newsize <= allocated拘央,則直接把ob_size設(shè)置成newsize涂屁。如果不在這個(gè)范圍內(nèi),就按如下方案realloc內(nèi)存:new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);
不是很理解為什么采用這個(gè)方案灰伟,求指教拆又。
刪除元素
刪除元素操作:實(shí)質(zhì)是函數(shù)app1的包裝。app1函數(shù)的關(guān)鍵操作是栏账,先找到第一個(gè)對(duì)象的位置遏乔,然后通過list_ass_slice函數(shù)將刪除點(diǎn)前后的兩段合并。