# `copy` --- Shallow and deep copy operations

Code source : Lib/copy.py

Les instructions d'affectation en Python ne copient pas les objets, elles créent des liens entre la cible et l'objet. Concernant les collections qui sont mutables ou contiennent des éléments mutables, une copie est parfois nécessaire, pour pouvoir modifier une copie sans modifier l'autre. Ce module met à disposition des opérations de copie génériques superficielle et récursive (comme expliqué ci-dessous).

Résumé de l'interface :

copy.copy(obj)

  Return a shallow copy of obj.

copy.deepcopy(obj[, memo])

  Return a deep copy of obj.

copy.replace(obj, /, **changes)

  Creates a new object of the same type as obj, replacing fields with values from changes.

  Ajouté dans la version 3.13.

exception copy.Error

  Levée pour les erreurs spécifiques au module.

La différence entre copie superficielle et récursive n'est pertinente que pour les objets composés (objets contenant d'autres objets, comme des listes ou des instances de classe) :

- Une copie superficielle construit un nouvel objet composé puis (dans la mesure du possible) insère dans l'objet composé des références aux objets trouvés dans l'original.

- Une copie récursive (ou profonde) construit un nouvel objet composé puis, récursivement, insère dans l'objet composé des copies des objets trouvés dans l'objet original.

On rencontre souvent deux problèmes avec les opérations de copie récursive qui n'existent pas avec les opérations de copie superficielle :

- Les objets récursifs (objets composés qui, directement ou indirectement, contiennent une référence à eux-mêmes) peuvent causer une boucle récursive.

- Comme une copie récursive copie tout, elle peut en copier trop, par exemple des données qui sont destinées à être partagées entre différentes copies.

La fonction `deepcopy()` évite ces problèmes en :

- gardant en mémoire dans un dictionnaire `memo` les objets déjà copiés durant la phase de copie actuelle ; et

- laissant les classes créées par l'utilisateur écraser l'opération de copie ou l'ensemble de composants copiés.

This module does not copy types like module, method, stack trace, stack frame, file, socket, window, or any similar types. It does "copy" functions and classes (shallow and deeply), by returning the original object unchanged; this is compatible with the way these are treated by the `pickle` module.

Les copies superficielles de dictionnaires peuvent être faites en utilisant `dict.copy()`, et de listes en affectant un `slice` de la liste, par exemple, `copied_list = original_list[:]`.

Les classes peuvent utiliser les mêmes interfaces de contrôle que celles utilisées pour la sérialisation. Voir la description du module `pickle` pour plus d'informations sur ces méthodes. En effet, le module `copy` utilise les fonctions de sérialisation enregistrées à partir du module `copyreg`.

In order for a class to define its own copy implementation, it can define special methods `__copy__()` and `__deepcopy__()`.

object.__copy__(self)

  Called to implement the shallow copy operation; no additional arguments are passed.

object.__deepcopy__(self, memo)

  Called to implement the deep copy operation; it is passed one argument, the memo dictionary. If the `__deepcopy__` implementation needs to make a deep copy of a component, it should call the `deepcopy()` function with the component as first argument and the memo dictionary as second argument. The memo dictionary should be treated as an opaque object.

Function `copy.replace()` is more limited than `copy()` and `deepcopy()`, and only supports named tuples created by `namedtuple()`, `dataclasses`, and other classes which define method `__replace__()`.

object.__replace__(self, /, **changes)

  This method should create a new object of the same type, replacing fields with values from changes.

Voir aussi

Module `pickle`

  Discussion sur les méthodes spéciales utilisées pour gérer la récupération et la restauration de l'état d'un objet.