闡述PyString Object對象源代碼
Python也被稱為是一門非常透徹的語言,在當(dāng)初設(shè)計(jì)者當(dāng)初設(shè)計(jì)它的時候,大體的指導(dǎo)思想,就是對于一個特定的問題,只要有一種最好的方法來解決就OK了,下面對Python PyStringObject對象說明。
與定長對象不同,對于變長對象而言,對象維護(hù)的數(shù)據(jù)的長度在對象定義時是不知道的。對于PyIntObject來說,其維護(hù)的數(shù)據(jù)的長度在對象定義時就已經(jīng)確定了。是一個long變量的長度;而可變對象維護(hù)的數(shù)據(jù)的長度只能在對象創(chuàng)建時才能確定,考慮一下,我們只能在創(chuàng)建一個字符串或一個列表時才知道它們所維護(hù)的數(shù)據(jù)的長度,在此之前,對這個信息,我們一無所知。
在變長對象中,實(shí)際上還可分為可變對象(mutable)和不可變對象(immutable),可變對象是在對象創(chuàng)建之后,其維護(hù)的數(shù)據(jù)的長度還能變化的對象。比如一個list被創(chuàng)建后,可以向其中添加元素或刪除元素。
這些操作都會改變其維護(hù)的數(shù)據(jù)的長度;而不可變對象所維護(hù)的數(shù)據(jù)在對象創(chuàng)建之后就不能再改變了,比如Python中的string和tuple,它們都不支持添加或刪除的操作。本章我們將研究Python變長對象中的不可變對象——字符串對象。
在Python中,PyStringObject是對字符串對象的抽象和表示。PyStringObject對象是一個擁有可變長度內(nèi)存的對象,這一點(diǎn)非常容易理解,因?yàn)閷τ诒硎尽盚i”和”Python”的兩個不同的PyStringObject對象,其內(nèi)部需要的保存字符串內(nèi)容的內(nèi)存空間顯然是不一樣的。
但同時,PyStringObject對象又是一個不變對象(Immutable)。當(dāng)創(chuàng)建了一個PyStringObject對象之后,該對象內(nèi)部維護(hù)的字符串就不能再被改變了。這一點(diǎn)特性使得PyStringObject對象能作為PyDictObject的鍵值,但同時也使得一些字符串操作的效率大大降低,比如多個字符串的連接操作。
PyStringObject對象的聲明如下:
- [stringobject.h]
- typedef struct {
- PyObject_VAR_HEAD
- long ob_shash;
- int ob_sstate;
- char ob_sval[1];} PyStringObject;
在PyStringObject的定義中我們看到,在PyStringObject對象的頭部實(shí)際上是一個PyObject_VAR_HEAD,其中有一個ob_size變量保存著對象中維護(hù)的可變長度內(nèi)存的長度。雖然在PyStringObject的定義中,ob_sval是一個字符的字符數(shù)組。
但是ob_sval實(shí)際上是作為一個字符指針指向了一段內(nèi)存,這段內(nèi)存保存著這個字符串對象所維護(hù)的實(shí)際字符串,顯然,這段內(nèi)存不會只是一個字節(jié)。而這段內(nèi)存的實(shí)際長度(字節(jié)),正是由ob_size來維護(hù),這個機(jī)制是Python中所有擁有可變長度內(nèi)存的對象的實(shí)現(xiàn)機(jī)制。比如對于PyStringObject對象”Python”,ob_size的值就是6。
同C中的字符串一樣,PyStringObject內(nèi)部維護(hù)的字符串在末尾必須以’\0’結(jié)尾,但是由于字符串的實(shí)際長度是由ob_size維護(hù)的,所以PyStringObject表示的字符串對象中間是可能出現(xiàn)字符’\0’的,這一點(diǎn)與C語言中不同,因?yàn)樵贑中。只要遇到了字符’\0’,就認(rèn)為一個字符串結(jié)束了。所以,實(shí)際上,ob_sval指向的是一段長度為ob_size+1個字節(jié)的內(nèi)存,而且必須滿足ob_sval[ob_size] = ‘\0’。
【編輯推薦】