Python阻止复制对象作为参考

时间:2013-10-06 16:12:43

标签: python

是否可以在不复制引用的情况下在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中是否可行?

提前致谢。

5 个答案:

答案 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.copycopy.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)