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.