ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

如果Python字符串是不可变的,为什么如果我使用+=追加到它,它会保持相同的id?

2022-07-06 00:00:39  阅读:127  来源: 互联网

标签:... Python print str 字符串 id


Python中的字符串是不可变的,这意味着该值无法更改。但是,在以下示例中追加到字符串时,由于 id 保持不变,因此原始字符串内存似乎已被修改:

>>> s = 'String'
>>> for i in range(5, 0, -1):
...     s += str(i)
...     print(f"{s:<11} stored at {id(s)}")
... 
String5     stored at 139841228476848
String54    stored at 139841228476848
String543   stored at 139841228476848
String5432  stored at 139841228476848
String54321 stored at 139841228476848

相反,在以下示例中,id 会更改:

>>> a = "hello"
>>> id(a)
139841228475760
>>> a = "b" + a[1:]
>>> print(a)
bello
>>> id(a)
139841228475312
118

这是一个特定于CPython的优化,适用于被追加到碰巧没有其他活引用的情况。在这种情况下,解释器“作弊”,允许它通过重新分配(可以就位,具体取决于堆布局)和直接附加数据来修改现有字符串,并且经常在重复连接的循环中显着减少工作(使其行为更像a的摊销追加而不是每次复制操作)。除了未更改的之外,它没有可见的效果,因此这样做是合法的(除非在逻辑上被替换,否则具有现有引用的人都不会看到它发生变化)。strO(1)listO(n)idstrstr

你实际上不应该依赖它(非引用计数的解释器不能使用这个技巧,因为他们不知道是否有其他引用),根据PEP8的第一个编程建议str

代码的编写方式不应使Python的其他实现(PyPy,Jython,IronPython,Cython,Psyco等)不利。

例如,不要依赖 CPython 为 form 或 中的语句有效实现就地字符串串联。即使在CPython中,这种优化也很脆弱(它仅适用于某些类型),并且在不使用refcounting的实现中根本不存在。在库的性能敏感部分,应改用表单。这将确保在各种实现中以线性时间进行串联。a += ba = a + b''.join()

如果你想打破优化,有各种各样的方法可以做到这一点,例如,将你的代码更改为:

>>> while i!=0:
...     s_alias = s  # Gonna save off an alias here
...     s += str(i)
...     print(s + " stored at " + str(id(s)))
...     i -= 1
... 

通过创建别名,增加引用计数并告诉Python更改将在 其他位置可见来破坏它,因此它无法应用它。类似地,像这样的代码:s

s = s + a + b

不能使用它,因为首先发生,并产生一个临时的,然后必须添加到,而不是立即替换,并且优化太脆而无法尝试处理。几乎相同的代码,如:s + abs

s += a + b

艺术

s = s + (a + b)

通过确保最终串联始终是左操作数的位置,并且结果用于立即替换 来恢复优化。

标签:...,Python,print,str,字符串,id
来源: https://www.cnblogs.com/johnsdc/p/16449138.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有