[笔记]Python的字符串对象
2012-03-10 01:36
501 查看
PyStringObject定义在stringobject.h中,附有不少注释说明。
1. PyStringObject实际上是一组字符,以'\0'结尾,且因为有只是长度的变量,所以也可以包含'\0'作为内容。
2. PyStringObject是不可变对象,所以a = "hello"和a = "world"先后执行后,a指向的是不同的对象了。
3. PyStringObject保存了hash值避免重复计算。
4. 采用intern机制来处理相同的字符串对象。
结构体定义如下:
计算哈希值的算法有必要MARK下,以后可以参考使用。
intern机制是用来确保相同的值的字符串对象只有一个存在,并且使得比较操作可以仅仅通过指针比较来完成。
它实际上是维护了一个字典(dict/map)interned,当字符串被interned时,会查找字典中键的存在,如果没有则放入。
这种方法可以在空间上节省,并不能节省时间,因为要判断是否存在于interned字典中,需要先创建字符串对象,才能去表中查找。
此外,这种方法默认针对Python的关键字、单字符、空串等。
当然,Python也提供了intern()内置函数来缓存用户想要的字符串对象。
缓存hash值以及intern机制为解释器加速了20%。
最后,是关于字符串的连接。
比如:str = str1 + str2 + str3 + str4,由于PyStringObject is immutable,所以会为3个+号执行3次内存的分配和复制
而如果将待连接的字符串放入可迭代对象中,使用string_join(PyStringObject的join操作),就会一次计算所需的总共内存大小,一次分配,然后再全部复制过去。
JasonLee 2011.08.08 0:33
1. PyStringObject实际上是一组字符,以'\0'结尾,且因为有只是长度的变量,所以也可以包含'\0'作为内容。
2. PyStringObject是不可变对象,所以a = "hello"和a = "world"先后执行后,a指向的是不同的对象了。
3. PyStringObject保存了hash值避免重复计算。
4. 采用intern机制来处理相同的字符串对象。
结构体定义如下:
typedef struct { PyObject_VAR_HEAD //不定长对象 long ob_shash; //如果还没计算,为-1 int ob_sstate; //如果该字符串在interned字典中,则该标志不为0。而且在这种情况下,两个来自interned字典的引用不算进ob_refcnt char ob_sval[1]; //用来作为指针指向保存字符串的内存区域,包含ob_size+1个元素 } PyStringObject;
计算哈希值的算法有必要MARK下,以后可以参考使用。
static long string_hash(PyStringObject *a) { register Py_ssize_t len; register unsigned char *p; register long x; if (a->ob_shash != -1) return a->ob_shash; len = Py_SIZE(a); p = (unsigned char *) a->ob_sval; x = *p << 7; while (--len >= 0) x = (1000003*x) ^ *p++; x ^= Py_SIZE(a); if (x == -1) x = -2; a->ob_shash = x; return x; }
intern机制是用来确保相同的值的字符串对象只有一个存在,并且使得比较操作可以仅仅通过指针比较来完成。
它实际上是维护了一个字典(dict/map)interned,当字符串被interned时,会查找字典中键的存在,如果没有则放入。
这种方法可以在空间上节省,并不能节省时间,因为要判断是否存在于interned字典中,需要先创建字符串对象,才能去表中查找。
此外,这种方法默认针对Python的关键字、单字符、空串等。
当然,Python也提供了intern()内置函数来缓存用户想要的字符串对象。
缓存hash值以及intern机制为解释器加速了20%。
最后,是关于字符串的连接。
比如:str = str1 + str2 + str3 + str4,由于PyStringObject is immutable,所以会为3个+号执行3次内存的分配和复制
而如果将待连接的字符串放入可迭代对象中,使用string_join(PyStringObject的join操作),就会一次计算所需的总共内存大小,一次分配,然后再全部复制过去。
JasonLee 2011.08.08 0:33
相关文章推荐
- 《python源码剖析》笔记 python中的字符串对象
- A Byte of Python 笔记(2)基本概念:数、字符串、转义符、变量、标识符命名、数据类型、对象
- python cookbook 学习笔记 -- 1.3 测试一个对象是否是类字符串
- python 宝典 笔记 第十二章 存储数据和对象 (各种对象转换成字符串)
- Python源码学习笔记 3 字符串对象
- python学习笔记6-基本对象和流程语句整理
- Python源码学习笔记 2 整数对象
- python学习笔记五:字符串方法
- python学习笔记3(字符串)
- python学习-07-浅谈对象与类(笔记)
- Python 学习笔记 (1)—— 字符串、元组、列表、字典
- Python基础教程学习笔记----第三章 字符串
- 小甲鱼Python教程第15讲--python字符串格式化笔记及习题答案
- Javascript学习笔记-1(类型、变量、for语句、数组、字符串、原型对象、函数对象)
- 《python源码剖析》笔记 python中的Dict对象
- python将对象名的字符串类型,转化为相应对象的操作方法
- python学习笔记十 类文件对象
- 轻松python文本专题-判断对象里面是否是类字符串(推荐使用isinstance(obj,str))
- python cookbook 读书笔记1(字符串处理1)
- 【Python学习笔记】list/dict对象复制的误区与正确方法