如下演示代码:
这样设计的合理性是因为string类型在C#中是属于immutable的,即对string的修改,并不是在原来的内存块上修改,而是重新开辟一块新的空间,创建新的对象。Python的String同样也有驻留Python中,同样为immutable的String类型,也采用了这种字符串驻留机制。但Python中稍微有点小规则。1,长度为0和1的字符串,默认都采用了驻留机制。>>> a=''>>> b=''>>> a is bTrue>>> a='a'>>> b='b'>>> a is bFalse>>> a='!'>>> b='!'>>> a is b2.编译期间就确定了的字符串,也采用驻留机制,但是,仅限于以下这些字符:"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"先解释一下什么叫做编译期间,Python是解释型语言,但是事实上,它的解释器也可以是理解为是一种编译器,它负责将Python代码翻译成字节码,也就是.pyc文件,之后再由Python虚拟机运行。这一点,和.Net的Framework、Java虚拟机很类似。(更多相关内容可以参考《Learning Python》),因此有些代码会在翻译成字节码的时候,就自动的帮程序员预先计算了。我们可以通过dis方法(分解Python中的字节码 )来验证,可以通过python -m dis xxx.py这样的命令来查看举例:如下的一个Python文件test.pya='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 bFalse3.通过乘法运算符得到的字符串,长度必须小于20。不然也无驻留机制>>> a='abc'6 #长度18>>> b='abc'6 #长度18>>> a,b('abcabcabcabcabcabc', 'abcabcabcabcabcabc')>>> a is bTrue>>> a='abc'*7 #长度21>>> b='abc'7 #长度21>>> a is bFalse这样的设计目的是为了保护.pcy文件不会被错误代码搞的过大,例如有人写了‘abc’10**10这种代码。上述代码也可以通过dis方式看到不同处。
4.和C#的字符串一样,Pyhton也提供intern方法强制2个字符串指向同一个对象,如下代码:>>> import sys>>> a='abcdef!'>>> b='abcdef!'>>> a is bFalse>>> a=sys.intern(b)>>> a is bTrue5.实际上,对于整数数字,Python也会有驻留机制,但是只限于[-5,256]之间的数字。参考文档http://guilload.com/python-string-interning/http://www.laurentluce.com/posts/python-string-objects-implementation/