8.17. "copy" — Opérations de copie superficielle et récursive
*************************************************************

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 muables ou contiennent des éléments muables, 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(x)

   Renvoie une copie superficielle de *x*.

copy.deepcopy(x)

   Renvoie une copie récursive de *x*.

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.

* Because deep copy copies everything it may copy too much, such as
  data which is intended to be shared between copies.

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

* gardant en mémoire dans un dictionnaire 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.

Ce module ne copie pas les types tels que module, méthode, trace
d’appels, cadre de pile, fichier, socket, fenêtre, tableau, ou tout
autre type similaire. Il « copie » les fonctions et les classes
(superficiellement et récursivement), en retournant l’objet original
inchangé ; c’est compatible avec la manière dont ils sont traités par
le module "pickle".

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

Modifié dans la version 2.5: Added copying functions.

Classes can use the same interfaces to control copying that they use
to control pickling.  See the description of module "pickle" for
information on these methods.  The "copy" module does not use the
"copy_reg" registration module.

Afin qu’une classe définisse sa propre implémentation de copie, elle
peut définir les méthodes spéciales "__copy__()" et "__deepcopy__()".
La première est appelée pour implémenter l’opération de copie
superficielle ; aucun argument supplémentaire n’est passé. La seconde
est appelée pour implémenter l’opération de copie récursive ; elle
reçoit un argument, le dictionnaire *memo*. Si l’implémentation de
"__deepcopy__()" a besoin de faire une copie récursive d’un composant,
elle devrait appeler la fonction "deepcopy()" avec le composant comme
premier argument et le dictionnaire *memo* comme second argument.

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.
