"copy" --- 浅いコピーおよび深いコピー操作
*****************************************

**ソースコード:** Lib/copy.py

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

Python において代入文はオブジェクトをコピーしません。代入はターゲット
とオブジェクトの間に束縛を作ります。ミュータブルなコレクションまたはミ
ュータブルなアイテムを含むコレクションについては、元のオブジェクトを変
更せずにコピーを変更できるように、コピーが必要になることが時々あります
。このモジュールは、汎用的な浅い (shallow) コピーと深い (deep) コピー
の操作 (以下で説明されます) を提供します。

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

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*.

   バージョン 3.13 で追加.

exception copy.Error

   モジュール特有のエラーを送出します。

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

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

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

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

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

* 深いコピーは何もかもコピーしてしまうため、例えば複数のコピー間で共有
  するつもりだったデータも余分にコピーしてしまいます。

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

* 現時点でのコピー過程ですでにコピーされたオブジェクトの "memo" 辞書を
  保持する。

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

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

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

クラスは、コピーを制御するために pickle の制御に使用するのと同じインタ
ーフェースを使用することができます。これらのメソッドについての情報はモ
ジュール "pickle" の説明を参照してください。実際、 "copy" モジュールは
、 "copyreg" モジュールによって登録された pickle 関数を使用します。

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*.

参考:

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