En Python, la copie des objets peut être superficielle (shallow copy) ou profonde (deep copy). Une copie superficielle crée un nouveau conteneur, mais les objets imbriqués ne sont pas copiés, mais se réfèrent aux mêmes objets. Une copie profonde crée récursivement de nouvelles copies de tous les objets imbriqués, garantissant l'indépendance de la copie.
Le module copy fournit les méthodes copy() (shallow copy) et deepcopy() (deep copy) :
import copy original = [[1, 2], [3, 4]] shallow = copy.copy(original) deep = copy.deepcopy(original) shallow[0][0] = 99 print(original) # [[99, 2], [3, 4]] ← l'objet d'origine a été modifié ! deep[1][1] = 42 print(original) # [[99, 2], [3, 4]] - pas modifié
Quelle est la différence entre l'opérateur
list2 = list1et l'utilisation de copy.copy(list1) ?
Réponse : L'opérateur list2 = list1 crée une nouvelle référence vers le même objet. copy.copy(list1) effectue une copie superficielle, créant un nouvel objet-liste, mais avec les mêmes objets internes. Pour les structures imbriquées, une copie superficielle n'est pas suffisante - une deep copy est nécessaire.
Histoire
Lors du développement d'API REST, les données du modèle étaient copiées par simple affectation (
data = template). La requête suivante a accidentellement modifié le "modèle" pour tous les utilisateurs suivants, car la même référence était utilisée.
Histoire
Dans le module de rapport, les données étaient copiées via
copy.copy(), bien que la structure soit imbriquée (listes dans des dictionnaires). Les modifications effectuées sur la copie se reflétaient de manière inattendue dans les données d'origine, entraînant des erreurs dans les statistiques.
Histoire
Dans un projet bancaire, une copie incorrecte d'un objet complexe imbriqué via
copy.copy()(et nondeepcopy()) a entraîné la perte de l'historique des transactions - de nouvelles opérations écrasaient les anciennes, car les éléments imbriqués étaient partagés.