Reputation: 696
I want to pass a list of objects to a function, get a new modified list but keep the original list unchanged. Like this:
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
It prints 5 and 5. Both are changed. I understand that the list itself is shallow copied, but for objects the value of reference is copied (which is why they are tied).
To shallow copy objects as well, I tried this:
array2 = [copy.copy(o) for o in array]
but it gives me an error:
print array[1].field1
AttributeError: classA instance has no attribute 'field1'
What is an easy way to shallow copy the objects inside the list too? Or maybe in general an easier way to do what I am trying to do?
Upvotes: 0
Views: 206
Reputation:
You need to make field1
and field2
instance attributes of classA
:
def __init__(self):
self.field1 = 0
self.field2 = 0
Without prefixing the names with self.
, field1
and field2
will be created as local names that are only available inside the __init__
method.
Also, it looks like you should actually be doing a deep copy of the list:
array2 = copy.deepcopy(array)
This will copy both the list object itself as well as all of its items. Doing a shallow copy will only copy the list object. From the docs:
A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
Upvotes: 2
Reputation: 8614
The way you defined it, field1
is not a field/attribute of the class, it is a local variable in the __init__()
method.
Instead, the proper way to declare a class field would be like this:
def __init__(self):
self.field1 = 0
self.field2 = 0
Upvotes: 0