繁体   English   中英

Python中的可变和不可变

[英]Mutable and Immutable in Python

我是Python新手,试图理解可变对象和不可变对象之间的区别。 Python中的一个可变类型是list。 假设L = [1,2,3],则L有一个id指向对象[1,2,3]。 如果[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

你真的不应该连续两次看到相同的ID,但CPython有一个优化的字符串连接+ ,它不完全遵守它应该的所有规则。

当CPython看到x = x + somethingx += something形式的操作时,如果x引用一个字符串并且x保存对该字符串的唯一引用,那么CPython将使用realloc增长该字符串而不是创建一个新的字符串对象。 根据可用内存的详细信息, realloc可以调整已分配的内存大小,也可以分配新内存。 如果它调整分配大小,则对象的id保持不变。 您可以在Python/ceval.c中的unicode_concatenate中看到实现。

这种优化大多很好,因为refcount检查确保它的行为大部分就像字符串真的是不可变的并且创建了一个新的字符串。 然而,在x = x + stuff ,老的字符串和新字符串应该有短暂重叠的寿命,因为新的字符串应该进入存在分配结束旧字符串的生命周期之前,所以它应该是不可能的ID值是等于。

如果没有发生字符串突变,则id是优化与显着不同的几种方式之一。 语言开发人员似乎已经决定他们对此没问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM