Python中的可变和不可变

bl

我是Python的新手,试图了解可变和不可变对象之间的区别。Python中的可变类型之一是列表。假设L = [1,2,3],则L具有指向对象[1,2,3]的ID。如果[1,2,3]的内容被修改,则L仍保留相同的id。换句话说,即使对象的大小和内容已更改,L仍与同一对象关联。

对于不可变的对象,我的理解是不允许修改对象。因此,如果使用新值重新分配变量,则该变量将绑定到具有不同ID的新对象。我希望字符串的行为类似。但是我尝试修改一个字符串,但是字符串id并没有改变。

string = "blue"
for i in range(10):
    string = string + str(i)
    print("string id after {}th iteration: {}".format(i,id(string)))


string id after 0th iteration: 46958272
string id after 1th iteration: 46958272
string id after 2th iteration: 46958272
string id after 3th iteration: 47077400
string id after 4th iteration: 47077400
string id after 5th iteration: 47077400
string id after 6th iteration: 47077400
string id after 7th iteration: 47077400
string id after 8th iteration: 47077400
string id after 9th iteration: 47077400
user2357112支持Monica

您确实不应该连续两次看到相同的ID,但是CPython对字符串连接进行了优化,但+并没有完全遵守它应该遵循的所有规则。

当CPython看到形式为x = x + something的操作时x += something,如果x引用一个字符串并x保存对该字符串唯一引用,则CPython将使用realloc扩展该字符串,而不是创建新的字符串对象。根据可用内存的详细信息,realloc可能会在适当位置调整已分配内存的大小,或者可能会分配新内存。如果它调整分配大小,则对象的id保持不变。您可以在unicode_concatenate查看实现Python/ceval.c

这种优化在大多数情况下都很好,因为refcount检查可确保它的行为几乎就像字符串确实是不可变的,并且创建了新的字符串一样。但是,在中x = x + stuff,旧字符串和新字符串的生存期短暂重叠,因为新字符串应在赋值结束旧字符串的生存期之前就已存在,因此ID值应该不可能相等。

id这是优化的显着不同于未发生字符串突变的几种方法之一。语言开发人员似乎已经决定可以接受。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章