设为首页 收藏本站
查看: 1928|回复: 0

[经验分享] Python中的字符串驻留

[复制链接]

尚未签到

发表于 2018-8-6 11:18:19 | 显示全部楼层 |阅读模式
  C#中的字符串驻留
  熟悉.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));
  如下演示代码:
DSC0000.jpg

  这样设计的合理性是因为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)
  运行:
DSC0001.jpg

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

  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/

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-547556-1-1.html 上篇帖子: Python爬虫 下篇帖子: python基础学习_目录列表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表