开发者社区> 技术小甜> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Python中的字符串驻留

简介:
+关注继续查看

C#中的字符串驻留

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

1
2
3
4
5
6
7
8
9
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));

如下演示代码:

clipboard

这样设计的合理性是因为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)

运行:

clipboard[1]

可以看到,变量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方式看到不同处。

clipboard[2]

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/














本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1615356,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
python常用字符串及其操作
python常用字符串及其操作
27 0
Python-字符串相关操作
Python-字符串相关操作
23 0
史上最全python字符串操作指南!
日常编码中,大家会发现,太多时候我们需要对数据进行处理,而这数据不管是数组、列表、字典,最终都逃不开字符串的处理。 所以今天要来跟大家发散的聊聊字符串!
44 0
史上最全python字符串操作指南
日常编码中,大家会发现,太多时候我们需要对数据进行处理,而这数据不管是数组、列表、字典,最终都逃不开字符串的处理。 所以今天要来跟大家发散的聊聊字符串!
49 0
图解python | 字符串及操作
在Python中,字符串(String)是若干个字符的集合,是最常用的数据类型。就是一个字符串。本文详细讲解字符串的创建、访问、连接、运算、格式化、Unicode字符串和内建函数等知识。
76 0
初学Python——字符串相关操作
Pyhton中字符串的格式化输出在前面已经总结了,接下来介绍一些常用的字符串操作 先定义一个字符变量,以下的操作都以此为例: name=" my name is china " #(首尾有空格) 1.
900 0
Python与R的异同(二):字符串操作
字符串操作的差异 R本身设计初衷主要是用来处理矩阵运算这类数学问题,因此在字符串操作方面比较薄弱。Python并不是专门用来进行数学计算的,没有偏向性,字符串操作优良。
745 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Python系列直播第一讲——Python中的一切皆对象
立即下载
Python第五讲——关于爬虫如何做js逆向的思路
立即下载
Python 脚本速查手册
立即下载