前面分析了python內(nèi)置類型的組成結(jié)構(gòu),今天來具體說說python基本內(nèi)置類型的存儲問題。
先談?wù)刬nt
python內(nèi)部的int分為小整數(shù)和大整數(shù),小整數(shù)[-5,257),大整數(shù)即為其他的一些整數(shù)。
這樣分的理由是一般來說我們編程,循環(huán)呀啥的,小整數(shù)出現(xiàn)的情況比較多,至于為啥是從-5開始到257,這個估計是python作者的經(jīng)驗(yàn)了。
小整數(shù)對象的存儲數(shù)組為:
#define NSMALLNEGINTS 5
#define NSMALLPOSINTS 257
static PyIntObject * small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
small_ints被高大上的稱之為小整數(shù)“內(nèi)存池”,從python一運(yùn)行,小整數(shù)在內(nèi)存里面的位置就固定了,而且順序也定下來,2在1的后一個,2的后面是3,即-5,-4,-3,-2.....。那么大整數(shù)呢?在python里面定義一個大整數(shù),也不是定義一個就申請一下內(nèi)存,開辟一個空間。大整數(shù)有大整數(shù)的內(nèi)存池:
struct _intblock{
struct _intblock *next;
PyIntPbject objects[N_INTOBJECTS];
}
上面只是存儲大整數(shù)的一個塊,很多塊連起來,就成了一個單向鏈表。
假設(shè)系統(tǒng)剛剛開始,我們還只有一個這樣的塊,從感覺上來講,PyIntPbject objects[N_INTOBJECTS];肯定是存放具體對象的地方,也和小整數(shù)一樣連續(xù)存放,一個蘿卜一個坑?來個1億幾萬億怎么辦?所以不是這樣的,在這里python的設(shè)計者用了一個奇妙的方法。

原來,是拿著數(shù)組的空間當(dāng)鏈表用,ob_type經(jīng)過強(qiáng)制類型轉(zhuǎn)化后充當(dāng)了next指針的作用。
屢一下流程
申請一個整數(shù),比如1000;
取出頭指針(free_list)指向的元素,填充1000,頭指針后移。
刪除一個整數(shù);
把刪除的整數(shù)元素作為頭結(jié)點(diǎn)加入到free_list鏈表當(dāng)中。
string的字符存儲方式和int小整數(shù)的一樣,都是一個指針數(shù)組來指示位置的,但是字符串的不一樣,有inner和非inner的方式,inner方式的“abc”和“abc”的地址是一樣的,非inner方式,其內(nèi)存地址不一樣。
list和dict的和int與string有些不一樣,他們是實(shí)時申請的,但在釋放時,只釋放對象里面動態(tài)內(nèi)存的那一部分(即對象的內(nèi)容),對象本身是沒有被釋放的,把他的地址存在一個數(shù)組中,這個數(shù)組的實(shí)際作為一個棧,若有申請,則往這個數(shù)組里面取棧頂?shù)刂啡缓蟪跏蓟纯伞?/p>
python源碼基本的對象介紹到這里,下一章為pyc與PyCodeObject。