Python中的字符串驻留

C#中的字符串驻留

熟悉.NET的人都应该知道C#中的字符串驻留机制,.NET维护了一个驻留池,它会把在编译期间就相同的字符串只保留一份拷贝。如果仅在运行期间值才相同的字符串变量,.NET不会为这个2个相同的字符串变量指向同一份引用的。不过.NET提供了一个方法,让开发人员可以强制将两个相同的字符串指向同一个引用,使用String类中的Intern方法。

string s1 = "!QAZ2wsx3$%5$$%fe _ ###[email protected]";
string s2 = "!QAZ2wsx3$%5$$%fe _ ###[email protected]";
Console.WriteLine("s1,s2是否引用同一对象:" + object.ReferenceEquals(s1, s2));
string s3 = "bbbbb";
string s4 = string.Concat("bbb", "bbb");
Console.WriteLine("s3,s4是否引用同一对象:" + object.ReferenceEquals(s3, s4));
Console.WriteLine("调用Intern后..." );
s3 = String.Intern(s4);
Console.WriteLine("s3,s4是否引用同一对象:" + object.ReferenceEquals(s3, s4));

如下演示代码:

这样设计的合理性是因为string类型在C#中是属于immutable的,即对string的修改,并不是在原来的内存块上修改,而是重新开辟一块新的空间,创建新的对象。

Python的String同样也有驻留

Python中,同样为immutable的String类型,也采用了这种字符串驻留机制。但Python中稍微有点小规则。

1,长度为0和1的字符串,默认都采用了驻留机制。

>>> a=‘‘

>>> b=‘‘

>>> a is b

True

>>> a=‘a‘

>>> b=‘b‘

>>> a is b

False

>>> a=‘!‘

>>> b=‘!‘

>>> a is b

2.编译期间就确定了的字符串,也采用驻留机制,但是,仅限于以下这些字符:

"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"

先解释一下什么叫做编译期间,Python是解释型语言,但是事实上,它的解释器也可以是理解为是一种编译器,它负责将Python代码翻译成字节码,也就是.pyc文件,之后再由Python虚拟机运行。这一点,和.Net的Framework、Java虚拟机很类似。(更多相关内容可以参考《Learning Python》),因此有些代码会在翻译成字节码的时候,就自动的帮程序员预先计算了。

我们可以通过dis方法(分解Python中的字节码 )来验证,可以通过python -m dis xxx.py这样的命令来查看

举例:如下的一个Python文件test.py

a=‘abcdef‘

b=‘abc‘+‘def‘

c=‘‘.join([‘abc‘,‘def‘])

print (a,b,c)

print (‘a and b are same?‘,a is b)

print (‘a and c are same?‘,a is c)

运行:

可以看到,变量a和b是同一个引用,但是a和c就不是了。再看其字节码,可以看出,a和b在赋值的时候,就是相同的字符串,但是c就不同了,它是几个字符串的拼装,它是在运行期间才知道结果。

注意,必须是字符串必须是在"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"中,不然就不支持字符串驻留。

比如:

>>> a=‘abcdef!‘

>>> b=‘abcdef!‘

>>> a is b

False

3.通过乘法运算符得到的字符串,长度必须小于20。不然也无驻留机制

>>> a=‘abc‘*6                  #长度18

>>> b=‘abc‘*6                  #长度18

>>> a,b

(‘abcabcabcabcabcabc‘, ‘abcabcabcabcabcabc‘)

>>> a is b

True

>>> a=‘abc‘*7 #长度21

>>> b=‘abc‘*7 #长度21

>>> a is b

False

这样的设计目的是为了保护.pcy文件不会被错误代码搞的过大,例如有人写了‘abc’*10**10这种代码。上述代码也可以通过dis方式看到不同处。

4.和C#的字符串一样,Pyhton也提供intern方法强制2个字符串指向同一个对象,如下代码:

>>> import sys

>>> a=‘abcdef!‘

>>> b=‘abcdef!‘

>>> a is b

False

>>> a=sys.intern(b)

>>> a is b

True

5.实际上,对于整数数字,Python也会有驻留机制,但是只限于[-5,256]之间的数字。

参考文档

http://guilload.com/python-string-interning/

http://www.laurentluce.com/posts/python-string-objects-implementation/

时间: 2024-10-07 07:47:01

Python中的字符串驻留的相关文章

Python中Unicode字符串

Python中Unicode字符串 字符串还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),0 - 255被用来表示大小写英文字母.数字和一些符号,这个编码表被称为ASCII编码,比如大写字母 A 的编码是65,小写字母 z 的编码是122. 如果要表示中文,显然一个字节是不够的,至少需要两个字节,而且

零基础学python-7.1 python中的字符串简介与常用函数

在python中,字符串变成了一个强大的处理工具集,他是不可变的,也就是说字符串包含字符与字符的顺序,他不可以原处修改 字符串是我们后面需要学习的稍大一点的对象类别--序列的第一个代表 在字符串章节所说到的关于序列的操作,后面的列表与元组一样适用 字符串常用的一些操作与函数 操作 解释 s='' 空字符串 s="abc'd" 双引号和单引号相同 s='abc\n' 转义序列,使用变量完全显示字符, 只有使用print函数才能够显示转义 s="""aaaaa

Python中的字符串处理

Python转义字符 在需要在字符中使用特殊字符时,python用反斜杠(\)转义字符.如下表: 转义字符 描述 \(在行尾时) 续行符 \\ 反斜杠符号 \' 单引号 \" 双引号 \a 响铃 \b 退格(Backspace) \e 转义 \000 空 \n 换行 \v 纵向制表符 \t 横向制表符 \r 回车 \f 换页 \oyy 八进制数yy代表的字符,例如:\o12代表换行 \xyy 十进制数yy代表的字符,例如:\x0a代表换行 \other 其它的字符以普通格式输出 Python字符

《python源码剖析》笔记 python中的字符串对象

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.      PyStringObject --> 变长不可变对象 typedef struct{ PyObject_VAR_HEAD//ob_size变量保存着对象中维护的可变长度内存的大小 longob_shash; //缓存该对象的hash值,用于dict的查询 intob_sstate; //标志该对象是否经过intern机制的处理 char ob_sval[1];// 字符指针

[笔记] 创建python中的字符串translator

将python中的字符串的某些字符转化为特定字符是经常用到string库中的maketrans()函数,以及translate()函数. 但是这两个函数比较抽象: maketrans函数产生的对象是一个表,这个数据结构对初学者并不友好. tranlate(table, deleteValue)函数所需的第一个参数是个表结构,也就是maketrans的返回值,deleteValue是所要删除的字符.这第二个参数很别扭:一个translate函数,有时候还能删除某些字符. 而且使用过程中,往往两个函

python中修改字符串的值

demo: info = 'abc' 如果要把上面的字符串info里面的c替换成d,要怎么操作呢? 方法一:使用python中的replace()方法 语法: str.replace(old, new[, max]) 参数: old -- 将被替换的子字符串. new -- 新字符串,用于替换old子字符串. max -- 可选字符串, 替换不超过 max 次 >>> info = "abc" >>> str = info.replace("

Python中的字符串

在Python中,字符串的类型可以归为三类:str,bytes,bytearray,其中str和bytes是不可变类型,而bytearray是可变类型.由于Python 2.X和Python 3.X的区别,相应的,它们在Python 2.X和Python 3.X中有不同的意义. 在Python 2.X中,str即可以表示8bit的文本(例如ASCII文本,Latin-1文本),也可以表示二进制数据,也就是说,在Python 2.X中,str和bytes类型是等价的:如果要表示Unicode文本,

python中分割字符串split切割并选择输出 逐行读取文件后字符串拼接

字符串根据分隔符切割后输出,一下面 #!/usr/bin/python # -*- coding: utf-8 -*- str="abc,123 efg,567" #以空行分割后输出 print str.split(); #以','分割2次后输出 print str.split(',',2); #以','分割2次后输出地2个参数,1是从0开始,代表第二个参数 print str.split(',',2)[1]; 输出结果如下: ['abc,123', 'efg,567'] ['abc'

Python中去除字符串中空格的方法

Python中去除字符串中指定字符或者空格的方法有几种: str.strip() //该方法用于去除字符串开头和结尾的指定字符或字符串(默认为空格或换行符) str.lstrip() //该方法用于截掉字符串左边的空格或指定字符 str.rstrip() //该方法用于截掉字符串右边的空格或指定字符 所以若是要去除字符串中所有的空格可以使用如下方式: str.strip().lstrip.rstrip() 原文地址:https://www.cnblogs.com/EdenChanIy/p/993