
:mod:`copy` --- 浅いコピーおよび深いコピー操作
==============================================

.. module:: copy
   :synopsis: 浅いコピーおよび深いコピー操作。


.. index::
   single: copy() (in copy)
   single: deepcopy() (in copy)

このモジュールでは汎用の (浅い／深い) コピー操作を提供しています。

以下にインタフェースをまとめます::

   import copy

   x = copy.copy(y)        # make a shallow copy of y
   x = copy.deepcopy(y)    # make a deep copy of y

このモジュール固有のエラーに対しては、 :exc:`copy.error`  が送出されます。


浅い (shallow) コピーと深い (deep) コピーの違いが関係するのは、複合オブジェクト (リストやクラスインスタンスのような他のオブジェクトを
含むオブジェクト) だけです:

* *浅いコピー (shallow copy)* は新たな複合オブジェクトを作成し、その後 (可能な限り) 元のオブジェクト中に見つかったオブジェクトに対する
  *参照* を挿入します。

* *深いコピー (deep copy)* は新たな複合オブジェクトを作成し、その後元のオブジェクト中に見つかったオブジェクトの *コピー* を挿入します。

深いコピー操作には、しばしば浅いコピー操作の時には存在しない 2 つの問題がついてまわります:

* 再帰的なオブジェクト (直接、間接に関わらず、自分自身に対する参照を持つ複合オブジェクト) は再帰ループを引き起こします。

* 深いコピーでは、*何もかも* をコピーするため、例えば複数のコピー間で共有されるべき管理データ構造までも、余分にコピーしてしまいます。

:func:`deepcopy` 関数では、これらの問題を以下のようにして回避しています:

* 現在のコピー過程ですでにコピーされたオブジェクトからなる、 "メモ" 辞書を保持します; かつ

* ユーザ定義のクラスでコピー操作やコピーされる内容の集合を上書きできるようにします。

このモジュールでは、モジュール、メソッド、スタックトレース、スタックフレーム、ファイル、ソケット、ウィンドウ、アレイ、その他これらに
類似の型をコピーしません。このモジュールでは元のオブジェクトを変更せずに返すことで関数とクラスを (浅くまたは深く)「コピー」します。これは
:mod:`pickle` モジュールでの扱われかたと同じです。

辞書型の浅いコピーは :meth:`dict.copy` で、リストの浅いコピーはリスト全体を指す
スライス (例えば ``copy_list = original_list[:]``) でできます。

.. versionchanged:: 2.5
   関数コピーの追加.

.. index:: module: pickle

クラスでは、pickle 化を制御するためのインタフェースと同じインタフェースをコピーの制御に使うことができます。これらのメソッドに関する情報は
:mod:`pickle` モジュールの記述を参照してください。 :mod:`copy` モジュールは pickle 用関数登録モジュール
:mod:`copy_reg` を使いません。

.. index::
   single: __copy__() (copy protocol)
   single: __deepcopy__() (copy protocol)

クラス独自のコピー実装を定義するために、特殊メソッド :meth:`__copy__` および :meth:`__deepcopy__`
を定義することができます。前者は浅いコピー操作を実装するために使われます; 追加の引数はありません。後者は深いコピー操作を実現するために呼び出されます;
この関数には単一の引数としてメモ辞書が渡されます。 :meth:`__deepcopy__`
の実装で、内容のオブジェクトに対して深いコピーを生成する必要がある場合、 :func:`deepcopy` を呼び出し、最初の引数にそのオブジェクトを、
メモ辞書を二つ目の引数に与えなければなりません。


.. seealso::

   Module :mod:`pickle`
      オブジェクト状態の取得と復元をサポートするために使われる特殊メソッドについて議論されています。

