Copie d'objets¶

Nous avons vu à la leçon 2 Stockage des variables en mémoire la différence entre les variables immuables qui sont copiées lorsque assignées à une nouvelle variable et les variables mutables qui sont de simples liens lorsqu’elles sont assignées à de nouvelles variables. Nous avons également constaté dans ce cours quelques problèmes liés à ces différents types de variables.

Voyons maintenant des problèmes liés à la copie d'objets.

Les objets sont mutables et sont donc copiés sous forme de vue (c’est-à-dire pas copiés).

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

La bibliothèque copy pour une véritable copie¶

Pour créer une copie réelle d'un objet, nous devons utiliser la bibliothèque 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

Cela semble correct mais il y a un piège. Et si ma classe a une variable mutable comme une liste ?

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 la copie n'est pas récursive ! C'est ce qu'on appelle une copie superficielle. Pour avoir une copie réelle, nous devons utiliser la fonction deepcopy de la même bibliothèque :

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 [ ]: