需要澄清Python中字符串的不变性

2024-09-27 09:37:24 发布

您现在位置:Python中文网/ 问答频道 /正文

字符串在Python中是不可变的,但在下面的示例中,一旦我开始将字母连接到初始字符串,就会生成一个新id,该id将保持不变,直到我将一个新字符串分配给相同的名称reversedString。根据我对不变性的理解,在每个连接中必须分配新的id,因为字符串是不可变的,而不像列表。请澄清同样的问题

sample = "hello"
print(id(sample)) # 1635882773744

sample += "A"
print(id(sample)) # 1635885488752

sample += "D2"
print(id(sample)) # 1635885488752

sample += "EWWW"
print(id(sample)) # 1635885488752

sample = "R"
print(id(sample)) # 1635795667504

输出:

1635882773744
1635885488752
1635885488752
1635885488752
1635795667504

Tags: sample字符串名称id示例hello列表字母
3条回答

id()提供存储变量的地址。当然,每当你改变这个变量时,这种情况就会改变。id()将与您提到的不同。每次都会改变。检查地址并不能说明您正在检查字符串的不变性

有关字符串的更多说明,请查看以下链接: https://www.python.org/dev/peps/pep-3137/

在CPython中,id与字符串在内存中的存储位置有关。它并不表示任何关于易变性的信息。如何准确地使用内存是一个内部实现细节。当然,您可以深入研究CPython内存管理的内部结构,以深入了解这些内容,但这并不是真正有用的。(Im)易变性可以简单地证明:

>>> foo = 'bar'
>>> baz = foo
>>> id(foo), id(baz)
(4402654512, 4402654512)
>>> foo += 'quux'
>>> print(foo, baz)
barquux bar
>>> foo[1] = 'o'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

使用+=改变foo不会使baz发生突变,即使它们曾经引用同一个对象。直接通过订阅(foo[1] = ...)更改字符不起作用并引发错误。这证明了字符串的不变性。在执行期间如何分配内存与此无关

Python解释器似乎有一些优点。它检测到变量sample的旧值正在被丢弃,并且它可以重用存储旧值的空间。因此,旧值和新值以相同的id()结束,即使它们是不同的对象

如果将三个sample += ...中的每一个替换为

temp = sample
sample += ...

你会发现每次都会得到不同的id()。我们阻止Python立即回收空间,因为另一个变量持有旧值

字符串是不可变的。你没有必要“测试”它。一旦字符串明显失效,Python就可以随意重用其空间。您不能期望ID在所有对象(包括活对象和死对象)中都是唯一的

相关问题 更多 >

    热门问题