制作对象列表的浅表副本

时间:2014-12-09 21:08:38

标签: python list copy shallow-copy

我想将一个对象列表传递给一个函数,获取一个新的修改列表,但保持原始列表不变。像这样:

class classA():
def __init__(self):
    field1 = 0
    field2 = 0

def func(array):    
    array2 = copy.copy(array) #array[:] gives the same result
    for index, q in enumerate(array):
        if index == 1:
            array2[index].field1 = 5
    return array2

array = [classA(),classA(),classA(),classA()]
array_new = func(array)

print array[1].field1
print array_new[1].field1

它打印5和5.两者都改变​​了。我理解列表本身是浅层复制的,但是对于对象,复制了引用的值(这就是为什么它们被绑定)。

对于浅拷贝对象,我试过这个:

array2 = [copy.copy(o) for o in array]

但它给了我一个错误:

  print array[1].field1
AttributeError: classA instance has no attribute 'field1'

什么是浅层复制列表中对象的简单方法?或者通常可以更简单的方式来做我想做的事情?

2 个答案:

答案 0 :(得分:2)

您需要field1的{​​{1}}和field2个实例属性:

classA

如果不使用def __init__(self): self.field1 = 0 self.field2 = 0 为名称加前缀,则self.field1将创建为仅在field2方法中可用的本地名称。


此外,看起来你应该真正做一个列表的deep copy

__init__

这将复制列表对象本身及其所有项目。执行浅拷贝只会复制列表对象。来自文档:

  

浅复制构造一个新的复合对象,然后(尽可能)将对它的引用插入到找到的对象中   原来。

     

深层复制构造一个新的复合对象,然后递归地将复制到其中的对象中插入   原始

答案 1 :(得分:0)

您定义它的方式,field1不是类的字段/属性,它是__init__()方法中的局部变量。 相反,声明类字段的正确方法是这样的:

def __init__(self):
    self.field1 = 0
    self.field2 = 0