Python字符串是不可变的?

时间:2012-12-18 11:55:55

标签: python string python-3.x immutability

Python字符串应该像整数一样是可以改变的。考虑一下:

>>> num1 = 34
>>> num2 = 36
>>> id(num1)
505894832
>>> num4 = 34
>>> id(num4)
505894832

num4具有与num1完全相同的ID,这意味着它们指向相同的东西。字符串不应该发生同样的事情吗?我很困惑:

>>> name = "Sumeet"
>>> id(name)
35692000
>>> name = "Ali"
>>> id(name)
35926912
>>> naam = "Sumeet"
>>> id(naam)
35926848

最后的输出不应该是:35692000

3 个答案:

答案 0 :(得分:5)

几个变量具有相同id的事实与实际对象不可变无关。

事实上,由于它们的不变性,这可以安全地发生(节省内存)。

让我们假设python中的字符串不是不可变的,你声明:

a = 'abc'

b = 'abc'

如果您更改了a,那意味着b将引用完全不同的对象(复制代表相同文字字符串所需的内存),或者a更改后,必须复制整个对象才能进行更改(以便b不会受到影响)。

由于字符串是不可变的,因此两个变量都可以安全地指向同一个对象。对不可变数据结构的任何更改都会创建一个新结构,并且指向它的引用将更改为新结构,而对“旧”结构的所有其他引用保持不变。不可变数据结构中没有副作用大大减少了由于共享结构/对象在代码中的其他位置发生更改而发生错误的可能性。

答案 1 :(得分:3)

CPython会实现一些非常小的整数和非常小的字符串,但你不能依赖它,因为它依赖于实现。

因此,以下是您的调查结果的一些反例:

>>> a = 123456
>>> b = 123456
>>> id(a)
30497296
>>> id(b)
30496144
>>> a = "hey"
>>> b = "hey"
>>> id(a)
44067112
>>> id(b)
44067112

答案 2 :(得分:2)

不是因为一个简洁明了的原因,它没有指向同一件事。

执行此操作时:

name = 'Sumeet'

您实质上是创建一个新的string对象并将其绑定到name引用。当你这样做时:

naam = 'Sumeet'

您再次创建 string对象并将其绑定到naam引用。为了让它们指向同一个对象,你应该这样做:

naam = name

这使naam引用name引用的同一对象。


关于整数,Python的CPython实现具有缓存小整数的功能。例如,根据this source python 3.2缓存从-5256的整数对象。