是否可以在不复制引用的情况下在Python中复制对象?
例如,如果我定义一个类
class SomeClass:
def __init__(self):
self.value = 0
然后创建一个实例
someObject = SomeClass()
someObject.value = 12
我尝试将其复制到另一个实例:
anotherObject = someObject
并尝试修改属性
anotherObject.value = 10
原始属性被修改:
print someObject.value #prints 10
有没有办法防止这种情况发生?为了澄清,我希望anotherObject.value
包含10
,但我希望someObject.value
仍然包含原始12
。这在python中是否可行?
提前致谢。
答案 0 :(得分:15)
问题是,
anotherObject = someObject
您不复制对象,只是添加另一个引用。要复制对象,请尝试以下操作:
from copy import copy
anotherObject = copy(someObject)
答案 1 :(得分:5)
import copy
obj2 = copy.deepcopy(obj2)
答案 2 :(得分:4)
正如您所注意到的那样,anotherObject = someObject
无法复制 - 如果您需要副本,请尝试
import copy
otherObject = copy.copy(someObject)
此处copy.copy
与copy.deepcopy
的区别非常重要 - 您可以使用copy.copy
为您所描述的简单对象,但更嵌套的对象需要{{1} }。
copy.deepcopy
只复制对象copy.copy(someObject)
,但如果someObject
包含对可以更改的其他对象的引用(“可变”对象),如
someObject
或
someObject.value.this_one_has_values_too = 4
或
someObject.value[0] = 1
然后引用将在副本中创建那些对象。如果您使用someObject.value['key'] = 'value'
,它们也会被复制。
了解这一点的好方法是使用Online Python Tutor(参见链接示例),但这里有一个简单的行为演示,没有在线Python教程提供的有用的图表。
copy.deepcopy
编辑:但是第一个例子中的整数怎么样?它实际上是在>>> import copy
>>> class Foo(object):
... pass
...
>>> f = Foo()
>>> f.value = 1
>>> f.nested_value = [2,3,4]
>>> deep = copy.deepcopy(f)
>>> deep.value = 5
>>> f.value
1
>>> deep.nested_value.append(6)
>>> f.nested_value
[2, 3, 4]
>>> shallow = copy.copy(f)
>>> shallow.value = 7
>>> f.value
1
>>> shallow.nested_value.append(8)
>>> f.nested_value
[2, 3, 4, 8]
对象和f
对象之间共享,但这不是问题 - 它不可编辑;我们不能将像shallow
这样的整数对象更改为任何不同的,所以我们不妨保存内存并在任何Python对象需要引用1时随时使用该对象。
要阅读的内容是Ned的Facts and Myths about Python names and values。
答案 3 :(得分:1)
您可以使用copy
。请尝试以下方法:
someObject = SomeClass()
someObject.value = 12
anotherObject = copy.copy(someObject)
anotherObject.value = 10
现在someObject.value
仍然是12.您必须将import copy
放在脚本的顶部。
答案 4 :(得分:1)
import copy
在某些情况下只是:
copy_obj = copy.copy(obj)
就足够了,但是在其他情况下,我们必须使用:
copy_obj = copy.deepcopy(obj)