我试图了解可变和不可变对象。我已经读过字符串是不可变的,并且对于每个字符串,使用不同的对象ID创建单独的对象。我试图使用下面的简单代码验证这一点,但是,我看到多个不相同的字符串的相同对象ID。有人可以澄清一下。提前谢谢。
mystring = ""
mylist = ["This ", "That ", "This ", "That ", "This ", "That ", "This ", "That "]
for item in mylist:
mystring = mystring + item
print("mystring: ", mystring, "ID of mystring: ", id(mystring))
导致以下输出:
mystring: This ID of mystring: 6407264
mystring: This That ID of mystring: 42523448
mystring: This That This ID of mystring: 42523448
mystring: This That This That ID of mystring: 6417200
mystring: This That This That This ID of mystring: 42785608
mystring: This That This That This That ID of mystring: 42785608
mystring: This That This That This That This ID of mystring: 42837536
mystring: This That This That This That This That ID of mystring: 42775856
答案 0 :(得分:3)
允许Python为具有非重叠生命周期的对象重用对象ID,但是在应该存在生命周期重叠的情况下,您会看到ID重用。具体而言,在执行此声明期间:
mystring = mystring + item
在mystring + item
的评估与mystring
的分配之间,mystring
的任意两个连续值之间应存在生命周期重叠。您将看到mystring
的连续值的ID重用,这不应该发生。
您所看到的效果是因为CPython字节码评估循环中的优化而发生的,其中表单的语句为
string1 = string1 + string2
或
string1 += string2
检测到,如果解释器可以确认string1
没有其他引用,它会尝试通过原位变更string1
来执行连接。您可以在Python/ceval.c
下的unicode_concatenate
中查看代码。由于引用计数检查,此优化通常是不可见的,但对id
值的影响是其可见的一种方式。
答案 1 :(得分:2)
String 是不可变的。没有允许变异的str
方法。
话虽这么说,你多次看到相同id的原因是因为当一个对象不再使用时,Python将重用它在内存中的位置。而id
所做的恰恰是通过返回对象在内存中的位置来提供唯一标识符。
一种说服自己的方法确实是您观察的原因是确保始终通过将您创建的每个字符串添加到list
来引用它。
mystring = ""
mylist = ["This ", "That ", "This ", "That ", "This ", "That ", "This ", "That "]
# A list to keep a reference to each string
created_strings = []
for item in mylist:
mystring = mystring + item
# Prevent mystring from being garbage collected by adding it to the list
created_strings.append(mystring)
print("mystring: ", mystring, "ID of mystring: ", id(mystring))
mystring: This ID of mystring: 2522900655888
mystring: This That ID of mystring: 2522903930416
mystring: This That This ID of mystring: 2522903930544
mystring: This That This That ID of mystring: 2522902118880
mystring: This That This That This ID of mystring: 2522900546624
mystring: This That This That This That ID of mystring: 2522900546864
mystring: This That This That This That This ID of mystring: 2522902428376
mystring: This That This That This That This That ID of mystring: 2522900907952
请注意,现在内存未被回收,每个对象都有不同的id
。