ProgrammationDéveloppeur Python

Décrivez la différence entre shallow copy et deep copy en Python. Comment copier correctement des structures de données imbriquées ? Comment fonctionne le module copy ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

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é

Question piégeuse.

Quelle est la différence entre l'opérateur list2 = list1 et 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.

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet.


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 non deepcopy()) 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.