You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python字符串拼接后id未改变,是否违背str对象的不可变特性?

现象解释

Python 语言规范中明确规定字符串是不可变对象,你观察到的id()不变的情况是 CPython 解释器独有的实现优化,不属于语言通用特性,也不违反字符串不可变的语义。

优化的具体逻辑

CPython 处理+=字符串增量拼接时,会先检查当前待拼接的字符串是否满足两个条件:

  • 该字符串当前只有唯一一处引用(没有其他变量、容器持有这个字符串对象)
  • 该字符串不属于字符串驻留池中的对象(小字符串、标识符默认会被驻留,全局共享引用)

如果满足条件,CPython 会直接在原内存地址上扩容字符串对象的存储空间,写入拼接后的新内容,不需要生成新的字符串对象,因此你观察到id()没有变化。

你的测试用例对应逻辑

  1. 初始的'a'属于驻留池的小字符串,有全局共享引用,不满足唯一引用条件,所以第一次拼接'b'时只能生成新的'ab'对象,id()发生变化。
  2. 新生成的'ab'对象不在驻留池中,且只有变量a一处引用,满足优化条件,第二次拼接'c'时直接在原内存地址扩容,id()保持不变。

反例验证

如果给字符串增加额外引用,优化就会失效,id()会按照不可变对象的预期发生变化:

>>> a = 'ab'
>>> b = a  # 给字符串新增一处引用
>>> id(a)
2844971374576
>>> a += 'c'
>>> id(a)
2844971381232  # id发生变化,生成新对象

注意事项

这个优化是 CPython 的内部实现细节,PyPy、Jython 等其他 Python 实现并不一定支持,也不保证后续 CPython 版本会保留该逻辑,写代码时绝对不要依赖这个行为,始终按照字符串不可变的语义开发。

内容的提问来源于stack exchange,提问作者itay zohar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 19:06:04