import copy
copy
module
One has to be careful when wanting to copy a variable/objects in Python as simple assigment doesn’t copy an object but just a reference. This problem is solver by the copy
module. For simple lists and dictionaries use copy.copy
, for class instances one must use copy.deepcopy
to actually copy an object. Following is example that illustrates this:
class Something():
= 1
a def __init__(self):
self.b = 1
self._value = 1
self.list = [1,1,1]
@property
def value(self):
return self._value
@value.setter
def value(self, value):
self._value = value
Let’s just assign a new variable p=s
, this will not be a copy but just a refernece to the same object:
= Something()
s = s
p id(p) == id(s)
True
If we now change p, s will change too:
def change_p_and_print(p, s):
print('s is initially:', s.a, s.b, s.value, s.list)
= 10
p.a = 10
p.b = 10
p.value list.append(10)
p.print('p is: ', p.a, p.b, p.value, p.list)
print('s is now: ', s.a, s.b, s.value, s.list)
print('s id:', id(s))
print('p id:', id(p))
change_p_and_print(p, s)
s is initially: 1 1 1 [1, 1, 1]
p is: 10 10 10 [1, 1, 1, 10]
s is now: 10 10 10 [1, 1, 1, 10]
s id: 4352964496
p id: 4352964496
Let’s now make a copy (aka shallow copy):
= Something()
s = copy.copy(s)
p change_p_and_print(p, s)
s is initially: 1 1 1 [1, 1, 1]
p is: 10 10 10 [1, 1, 1, 10]
s is now: 1 1 1 [1, 1, 1, 10]
s id: 4352951920
p id: 4352964352
So we see that non-list variables are now copied, but list
variable is still just referenced, and can be changed. As this website puts it: “a shallow copy doesn’t create a copy of nested objects, instead it just copies the reference of nested objects. This means, a copy process does not recurse or create copies of nested objects itself.”. id
-s are now different.
To make a proper (i.e. deep copy) we use deep copy.
= Something()
s print(s.a, s.b, s.value, s.list)
= copy.deepcopy(s)
p change_p_and_print(p, s)
1 1 1 [1, 1, 1]
s is initially: 1 1 1 [1, 1, 1]
p is: 10 10 10 [1, 1, 1, 10]
s is now: 1 1 1 [1, 1, 1]
s id: 4352956480
p id: 4421994192