当我需要在Python中显式复制对象以便在不改变原始内容的情况下进行更改时,我有点困惑。 Python doc page没有太多细节,只是说“赋值语句不会创建副本”。
示例1:
>>> a = 4
>>> b = a
>>> b += 1
>>> print(b)
>>> print(a)
# Results are what you'd "expect" them to be:
5
4
示例2:
>>> class Test():
>>> def __init__(self, x):
>>> self.x = x
>>>
>>> A = Test(4)
>>> B = A
>>> B.x += 1
>>> print(B.x)
>>> print(A.x)
# Unexpected results because B isn't actually a copy of A:
5
5
编辑:为了让示例2起作用,我基本上做了以下操作。我问为什么这不是示例1所必需的:
>>> import copy
>>> A = Test(4)
>>> B = copy.copy(A)
>>> B.x += 1
>>> print(B.x)
>>> print(A.x)
答案 0 :(得分:2)
在您的示例1中,您编写了b += 1
。这与撰写b = b + 1
是一回事。这使用=
运算符将值分配给b
。您只是更改名称b
引用的值。在示例2中,您正在更改两个名称(A
和B
)所引用的对象的属性。它们仍然在内存中引用相同的对象,因此更改该对象的.x
属性会同时更改B.x
和A.x
。
答案 1 :(得分:2)
a = 4
b = a
..意味着" make b
引用a
引用的任何内容"。在这种情况下,这将是4。由于整数为immutable,因此通过b
更改b += 1
会使其指向不同的对象
检查他们的ids:
a = 4
b = a
print(id(a)) # Same id
print(id(b)) # Same id
b = 123
print(id(b)) # Different id
当B不是.copy()
时,实例A和B也会发生同样的事情。
<强> ID 强>(对象)
返回对象的“身份”。
mutable 对象的一个有趣示例:
l = [1, 2]
k = l
print(id(l)) # Same id
print(id(k)) # Same id
k.append(3)
print(id(k)) # Same id
print(l, k) # Prints [1, 2, 3] [1, 2, 3]
append()
修改k
和l
引用的对象。它没有为k
分配不同的对象。
正如@blcckngth所说:
k = k + [3]
print(id(k)) # Different id ..
print(l, k) # ..prints [1, 2] [1, 2, 3]
而k += [3]
会导致引用同一个对象。