[python 源码]字符串对象的实现

时间:2023-03-10 04:28:30
[python 源码]字符串对象的实现

还是带着问题上路吧,和整数对象的实现同样的问题:

>>> a='abc'
>>> b='abc'
>>> a is b
True
>>> c='abc'*10
>>> d='abc'*10
>>> d is c
False

why?在整数对象的实现中,对待小整数有小整数对象池,对待大整数对申请内存,字符串对象的实验也是这样的吗???

NO

先看下字符串对象的定义:

typedef struct{
PyObject_VAR_HEAD
long ob_shash;
int ob_sstate;
char ob_sval[];
}PyStringObject;

其中:

PyObject_VAR_HEAD中的ob_size存放字符串实际长度

ob_shash用来缓存该字符串对象的实际hash值

ob_sstate标记该对象是否经过intern机制处理

ob_sval指向一段长度为ob_size+1字节的内存,ob_sval[ob_size+1]必须为'\0'

字符对象的创建就是计算字符串的长度,申请一段内存,把字符串用memcpy复制进去,然后创建这个对象,看好,所有的字符串都会创建对象。(代码就不贴了。。。)

重要的是intern机制,这个机制是什么东西?

说白了,intern机制就是每创建一个比较短的字符串对象,就在一个叫interned的字典里面查看是否存在字符串相同的字符串对象,如果存在的话,就把字典存放的对象的ob_refcnt加1,然后销毁新创建的对象,所以才会出现上面的情景   a is b?True

字符串对象除了intern机制以外,还有类似于小整数对象的字符缓冲池,其实就是用一个类似于数组的东西(characters array)指向这个对象,对只有一个字符的字符串,第一次创建时候会进行如下操作:

1.创建对象

2.对其进行intern操作

3.将对象放进字符缓冲池

[python 源码]字符串对象的实现

那么下次再创建这个字符对象时候,会首先查看字符缓冲池中是否存在这个对象,如果存在的话,返回这个缓冲对象。区别于小整数对象的是,小整数对象在python解释器初始化之初就创建了,而字符串缓冲池指向的对象直到用到的时候才会创建。

参考资料:

python源码剖析

Python string objects implementation