假设我执行以下操作:
>>> id(a)
139926795932424
>>> a
[1, 2, 3, 4]
>>> a = a + [5]
>>> id(a)
这个脚本的最后一行会打印 139926795932424 吗?或者一个新的 id 将分配给 a?
请您参考如下方法:
Will the last line of this script print 139926795932424? Or a new id will be assigned to a?
一个新的 id 将分配给 a。为什么?因为 a 指的是不同的对象。
a = a + [5] 是 a = a.__add__([5]) 的语法糖,因为 a.__add__([5 ]) 返回一个新对象,a 持有对新对象而不是旧对象的引用。这可以通过一个简单的例子来观察:
>>> a = [1, 2]
>>> b = a # copy the reference in a to b
>>> id(a) == id(b) # they match
True
>>> a = a + [5] # syntatic sugar for a = a.__add__([5])
>>> id(a) == id(b) # they no longer match
False
>>>
请注意,从这个意义上说,a = a + [5] 和 a += [5] 是不相同的,即使它们产生相同的结果 (a = [1, 2, 5])。上面所说的第一个例子是 a = a.__add__([5]) 的语法糖。而第二个是 a = a.__iadd__([5]) 的语法糖。区别在于后一种方法 - __iadd__() - 不在内存中创建新对象。相反,它修改现有 列表对象,并返回对它的引用。再次像以前一样:
>>> a = [1, 2]
>>> b = a # copy the reference in a to b
>>> id(a) == id(b) # they match
True
>>> a += [5]
>>> id(a) == id(b) # they still match, `b` has mutated too!
True
>>> b
[1, 2, 5]
