python源码剖析笔记-字符串

PyStringObject需要保存字符串长度(ob_size),当产生字符串对象后,将不会改变(不可变对象)。这一特性使得PyStringObject对象可作为dict的键值,同时也使一些字符串操作的效率大大降低了,比如字符串连接操作。   typedef struct { PyObject_VAR_HEAD long ob_shash; int ob_sstate; char ob_sval[1]; } PyStringObject;   同c语言一样,字符串末尾以‘\0’结尾,但是中间可以出现’\0’,ob_sval指向一段长度为ob_size+1个字节的内存,字符串结束需要满足ob_sval[ob_size] == ‘\0’   Ob_hash缓存该对象的hash值,初始值为-1。Ob_sstate在书后面介绍intern机制,对于被intern之后的字符串,在整个python运行期间,系统中都只有唯一一个与该字符串对应的PyStringObject对象。当判断两个PyStringObject对象是否相同时,如果都被intern了,只要检查对应的对象是否相同即可。   PyStringObject对应的类型对象为PyString_Type,tp_itemsize被设置成sizeof(char),即一个字节。与ob_size共同决定申请多少内存。 字符串对象有长度限制,大小为2GB。   Intern机制对相同字符串的处理: a = “python” b=”python” print a,b   intern机制的关键,是有一个叫interned的字典,记录intern机制处理过的PyStringObject对象。 对于上面的例子,先创建PyStringObject对象a,先会检查interned字典里有没有字符串与a相同,这里显然没有,将会添加到interned字典里。当创建b后(必须先要创建)执行intern操作,继续检查interned字典,发现有相同的字符串对象a,然后指向b的PyObject指针将指向a,b的引用计数减1,b将会被回收了。   有长度为256的字符缓冲池,添加到缓冲池的流程:当在创建PyStringObject对象时(还没创建),先检查长度。为字符时,再检查字符缓冲池是否有该字符,有,直接返回缓冲的该对象,结束;没有,创建PyStringObject对象,检查长度为字符,对对象进行intern操作,最后缓存至字符缓冲区。创建StringObject的两个函数不是太长也有注释,还能看懂。   字符串连接 通过”+”操作符对字符串进行连接是,调用string_concat函数:先计算连接后的字符串的长度,然后创建新的字符串对象分配给他计算的长度内存,最后复制。 Join操作,调用函数string_join:基本流程和“+”操作符相同。这里的区别是,“+”操作符有两个字符串就要创建一个新对象,join是对列表中的所有字符串进行,只要创建一次新对象就行。当进行多个字符串的连接时,应使用join操作。  

上一篇:
下一篇:

相关文章:

Categories: 博客记录

0 Responses so far.

Leave a Reply