C#中的字符串驻留python
熟悉.NET的人都应该知道C#中的字符串驻留机制,.NET维护了一个驻留池,它会把在编译期间就相同的字符串只保留一份拷贝。若是仅在运行期间值才相同的字符串变量,.NET才会为这个2个相同的字符串变量指向同一份引用的。不过.NET提供了一个方法,让开发人员能够强制将两个相同的字符串指向同一个引用,使用String类中的Intern方法。程序员
string s1 = "!QAZ2wsx3$%5$$%fe _ ###4@"; string s2 = "!QAZ2wsx3$%5$$%fe _ ###4@"; 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));
以下演示代码:c#
这样设计的合理性是由于string类型在C#中是属于immutable的,即对string的修改,并非在原来的内存块上修改,而是从新开辟一块新的空间,建立新的对象。ide
Python的String一样也有驻留post
Python中,一样为immutable的String类型,也采用了这种字符串驻留机制。但Python中稍微有点小规则。ui
1,长度为0和1的字符串,默认都采用了驻留机制。spa
>>> 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/