8.10. "copy" --- Operações de cópia profunda e cópia sombra
***********************************************************

**Código Fonte:** Lib/copy.py

======================================================================

As instruções de atribuição no Python não copiam objetos, elas criam
ligações entre um destino e um objeto. Para coleções que são mutáveis
​​ou contêm itens mutáveis, às vezes é necessária uma cópia para que
seja possível alterar uma cópia sem alterar a outra. Este módulo
fornece operações genéricas de cópia profunda e rasa (explicadas
abaixo).

Sumário da Interface:

copy.copy(x)

   Devolve uma cópia rasa de *x*.

copy.deepcopy(x[, memo])

   Retorna uma cópia profunda  de *x*.

exception copy.error

   Levantada para erros específicos do módulo.

A diferença entre cópia profunda e rasa é relevante apenas para
objetos compostos (objetos que contêm outros objetos, como listas ou
instâncias de classe):

* Uma *cópia rasa* constrói um novo objeto composto e então (na medida
  do possível) insere nele *referências* aos objetos encontrados no
  original.

* Uma *cópia profunda* constrói um novo objeto composto e então,
  recursivamente, insere nele *cópias* dos objetos encontrados no
  original.

Frequentemente, existem dois problemas com operações de cópia profunda
que não existem com operações de cópia rasa:

* Objetos recursivos (objetos compostos que, direta ou indiretamente,
  contêm uma referência a si mesmos) podem causar um laço recursivo.

* Como a cópia profunda copia tudo, ela pode copiar muito, como dados
  que devem ser compartilhados entre as cópias.

A função "deepcopy()" evita esses problemas:

* mantendo um dicionário "memo" de objetos já copiados durante a
  passagem de cópia atual; e

* permitindo que as classes definidas pelo usuário substituam a
  operação de cópia ou o conjunto de componentes copiados.

Este módulo não copia tipos como módulo, método, rastreamento de
pilha, quadro de pilha, arquivo, soquete, janela, matriz ou outros
tipos semelhantes. Ele "copia" funções e classes (rasas e profundas),
devolvendo o objeto original inalterado; isso é compatível com a
maneira que estes itens são tratados pelo módulo "pickle".

Cópias rasas de dicionários podem ser feitas usando "dict.copy()", e
de listas atribuindo uma fatia de toda a lista, por exemplo,
"lista_copiada = lista_original[:]".

As classes podem usar as mesmas interfaces para controlar a cópia que
usam para controlar o *pickling*. Veja a descrição do módulo "pickle"
para informações sobre esses métodos. Na verdade, o módulo "copy" usa
as funções pickle registradas do módulo "copyreg".

Para que uma classe defina sua própria implementação de cópia, ela
pode definir métodos especiais "__copy__()" e "__deepcopy__()". O
primeiro é chamado para implementar a operação de cópia rasa; nenhum
argumento adicional é passado. O último é chamado para implementar a
operação de cópia profunda; é passado um argumento, o dicionário
"memo". Se a implementação de "__deepcopy__()" precisa fazer uma cópia
profunda de um componente, ela deve chamar a função "deepcopy()" com o
componente como primeiro argumento e o dicionário de memorando como
segundo argumento.

Ver também:

  Módulo "pickle"
     Discussão dos métodos especiais usados ​​para dar suporte à
     recuperação e restauração do estado do objeto.
