Python中的可变和不可变 [英] Mutable and Immutable in Python

查看:71
本文介绍了Python中的可变和不可变的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to Python and trying to understand the difference between mutable and immutable objects. One of the mutable types in Python is list. Let's say L = [1,2,3], then L has a id that points the object [1,2,3]. If the content of [1,2,3] is modified then L still retains the same id. In other words L is still associated with the same object even though the size and content of the object has been altered.

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

With immutable objects, my understanding is that modification of the object isn't allowed. Therefore, if a variable is reassigned with a new value, then that variable is bind to a new object with a different id. I expect string to behave in similar manner. Yet I tried to modified a string but the string id didn't change.

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对 + 的字符串连接进行了优化,但没有这样做并没有完全遵守应有的规则.

You really shouldn't see the same ID twice in a row, but CPython has an optimization for string concatenation with + that doesn't quite obey all the rules it's supposed to.

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

When CPython sees an operation of the form x = x + something or x += something, if x refers to a string and x holds the only reference to that string, then CPython will grow the string with realloc instead of creating a new string object. Depending on details of available memory, realloc may resize the allocated memory in place, or it may allocate new memory. If it resizes the allocation, the object's id remains the same. You can see the implementation in unicode_concatenate in Python/ceval.c.

此优化主要很好,因为refcount检查可确保其表现为大部分,就好像字符串实际上是不可变的,并创建了新的字符串一样.但是,在 x = x + stuff 中,旧字符串和新字符串应该短暂地重叠,因为新字符串应在赋值结束旧字符串之前就已存在字符串的生存期,因此应该不可能使ID值相等.

This optimization is mostly fine, because the refcount check ensures it behaves mostly as if strings were really immutable and a new string was created. However, in x = x + stuff, the old string and the new string should have briefly overlapping lifetimes, because the new string should come into existence before the assignment ends the old string's lifetime, so it should be impossible for the ID values to be equal.

id 是优化的显着不同于未发生字符串突变的几种方法之一.语言开发人员似乎已决定对此表示满意.

id is one of the few ways the optimization is observably different from if no string mutation occurred. The language developers seem to have decided they're okay with that.

这篇关于Python中的可变和不可变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆