我想将一个对象列表传递给一个函数,获取一个新的修改列表,但保持原始列表不变。像这样:
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'
什么是浅层复制列表中对象的简单方法?或者通常可以更简单的方式来做我想做的事情?
答案 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