Object copy¶

We have seen in lesson 2 How variables are stored in memory the difference between immutable variables which are copied when assigned to a new variable and mutable variables which a links when assigned to new variables. We also have seen in that course few issues related to this different kinds of variables.

Now let's see issues related to copy of objets.

Objects are mutable and therefore are copied as view (i.e. not copied).

In [1]:
class A():
    def __init__(self):
        self.x = 1
        
a1 = A()
a2 = a1     # a2 is a pointer to a1 and not a copy

a1.x = 3    # we modify a1
print(a2.x) # we print  a2
3

The library copy to make real copies¶

To make a real copy of an object we should use the library copy :

In [2]:
from copy import copy

class A():
    def __init__(self):
        self.x = 1
        
a1 = A()
a2 = copy(a1)

a1.x = 3      
print(a2.x) 
1

It seems OK but there is a pitfall. What if my class has a mutable variable like a list?

In [3]:
class A():
    def __init__(self):
        self.x = [1,2,3]
        
a1 = A()
a2 = copy(a1) # a real real copy?

a1.x[0] = 10
print(a2.x)
[10, 2, 3]

Argh the copy is not recursive! It is called a shallow copy. To have a real copy we must use the deepcopy function of the same library:

In [4]:
from copy import deepcopy

class A():
    def __init__(self):
        self.x = [1,2,3]
        
a1 = A()
a2 = deepcopy(a1)

a1.x[0] = 10
print(a2.x)
[1, 2, 3]

{{ PreviousNext("03 Scope.ipynb", "10 Magic methods.ipynb")}}

In [ ]: