第一章 python的內(nèi)建對(duì)象
python中一切都是對(duì)象鹿鳖。在PyIntObject中定義了很多函數(shù)指針通铲,這些函數(shù)指針對(duì)應(yīng)著類型對(duì)象所定義的操作官辈。其中有三組非常重要的操作族援岩,tp_as_number, tp_as_sequence, tp_as_mapping,分別對(duì)應(yīng)著PyNumberMethods, PySequenceMethods, PyMappingMethods函數(shù)族锹锰,這三個(gè)函數(shù)都是分別定義著一個(gè)整數(shù)對(duì)象芥炭、序列對(duì)象、關(guān)聯(lián)對(duì)象應(yīng)該有的一些操作恃慧。在python中對(duì)于任何一種類型來(lái)說(shuō)园蝠,都可以同時(shí)定義三個(gè)函數(shù)族中的所有操作,也就是說(shuō)痢士,我們可以在繼承python固有的類型時(shí)彪薛,又同時(shí)重寫python的special method,從而實(shí)現(xiàn)我們自己定義的特殊類型怠蹂。比如可以實(shí)現(xiàn)一個(gè)對(duì)象善延,既可以表現(xiàn)出數(shù)值特性,也可以表現(xiàn)出關(guān)聯(lián)對(duì)象的屬性城侧。
第二章 python中的整數(shù)對(duì)象
python的整數(shù)對(duì)象易遣。在python中會(huì)有一個(gè)整數(shù)對(duì)象池,里面維護(hù)著-5到256之間的整數(shù)嫌佑,當(dāng)我們需要使用這些范圍的數(shù)字時(shí)豆茫,直接到對(duì)象池中去提取侨歉。這樣設(shè)計(jì)是因?yàn)樵趯?shí)際的開發(fā)中,這些小數(shù)可能會(huì)被頻繁的使用澜薄,頻繁的創(chuàng)建和湮滅會(huì)導(dǎo)致效率非常低为肮。對(duì)于超出這些范圍的數(shù)字,python底層則是通過單獨(dú)申請(qǐng)一塊內(nèi)存塊來(lái)給這些大整數(shù)輪流使用肤京,當(dāng)某個(gè)對(duì)象的引用次數(shù)為零的時(shí)候,會(huì)把該對(duì)象所占用的這塊內(nèi)存添加到空閑區(qū)(注意茅特,這里python并沒有將釋放的內(nèi)存還給系統(tǒng)忘分,所以當(dāng)出現(xiàn)很多大數(shù)要被使用的時(shí)候,而這些數(shù)又是使用一次白修,可能就會(huì)占用系統(tǒng)的所有內(nèi)存妒峦。)
第三章 python中的字符串對(duì)象
- 在python中,PyStringObject是字符串對(duì)象的實(shí)現(xiàn)兵睛,它是一個(gè)可變長(zhǎng)度內(nèi)存的對(duì)象肯骇,同時(shí)又是一個(gè)不可變對(duì)象(字符串定義之后不可再改變)。python字符串對(duì)象中的intern機(jī)制祖很,類似于前面的python整數(shù)對(duì)象池笛丙。其關(guān)鍵是在于在系統(tǒng)中有一個(gè)(key, value)的映射關(guān)系集合,集合名字叫做Intered假颇。在這個(gè)集合中記錄過被intern機(jī)制處理過的字符串胚鸯。當(dāng)python在創(chuàng)建一個(gè)字符串時(shí),首先會(huì)建立一個(gè)PyStringObject對(duì)象a笨鸡,然后利用intern機(jī)制處理姜钳,如果當(dāng)前這個(gè)字符串對(duì)象已經(jīng)在interned中存在,記為b形耗,則將指向a的對(duì)象的指針指向b哥桥,然后intern機(jī)制會(huì)將對(duì)象a的引用計(jì)數(shù)減為0而被銷毀。這樣的話激涤,可以達(dá)到減少內(nèi)存的目的拟糕。
也許會(huì)有一個(gè)問題,為什么一定要先創(chuàng)建一個(gè)臨時(shí)PyStringObject對(duì)象呢昔期?
這是因?yàn)閕ntern機(jī)制只能應(yīng)用在PyStringObject對(duì)象之上已卸,別的任何對(duì)象都不可以。因此這里必須要先創(chuàng)建一個(gè)臨時(shí)對(duì)象硼一。 - python中也為一個(gè)字節(jié)的字符設(shè)計(jì)了字符緩沖池累澡,與小整數(shù)對(duì)象池不一樣的是,小整數(shù)對(duì)象池在python初始化的時(shí)候就會(huì)被創(chuàng)建般贼,而字符串對(duì)象中的字符緩沖池是以靜態(tài)變量形式存在的愧哟,在python初始化完成之后奥吩,字符緩沖池是空的。當(dāng)python在創(chuàng)建一個(gè)PyStringObject的時(shí)候蕊梧,如果字符串長(zhǎng)度為1(即單個(gè)字符串)霞赫,則將會(huì)對(duì)這個(gè)字符進(jìn)行intern操作,將intern的這個(gè)結(jié)果緩存到字符緩沖池中肥矢。當(dāng)通過PyString_FromStringandSize(const char *str, int size)來(lái)創(chuàng)建字符對(duì)象時(shí)端衰,如果size等于1,并且在字符緩沖池中存在甘改,則直接返回旅东。
- python中字符串的連接效率問題。當(dāng)我們采用+號(hào)來(lái)連接多個(gè)字符串時(shí)十艾,效率是非常低的抵代。其根源在于,python中的字符串對(duì)象是一個(gè)不可變對(duì)象忘嫉,因此在連接兩個(gè)字符串的時(shí)候荤牍,則要去新建一個(gè)PyStringObject對(duì)象,當(dāng)我們用‘+’來(lái)連接N個(gè)字符串時(shí)庆冕,實(shí)際上會(huì)進(jìn)行N-1次內(nèi)存申請(qǐng)和內(nèi)存搬運(yùn)康吵,因而效率很低。解決方案是愧杯,我們采用字符串對(duì)象的join操作來(lái)實(shí)現(xiàn)多個(gè)字符串的連接涎才,當(dāng)使用join操作的時(shí)候,會(huì)一次性計(jì)算好需要的總的內(nèi)存力九,也就是只需要執(zhí)行一次內(nèi)存申請(qǐng)耍铜,因此效率會(huì)比用‘+’號(hào)連接的效率更高
strs_list = ['hello', 'fay', 'welcome', 'to', 'python ']
' '.join(strs_list)