copy —浅くて深いコピー操作
ソースコード: :source: `Lib / copy.py`
Pythonの代入ステートメントはオブジェクトをコピーせず、ターゲットとオブジェクトの間にバインディングを作成します。 可変または可変アイテムを含むコレクションの場合、一方が他方を変更せずに一方のコピーを変更できるように、コピーが必要になる場合があります。 このモジュールは、一般的な浅いコピー操作と深いコピー操作を提供します(以下で説明します)。
インターフェイスの概要:
- copy.copy(x)
- x の浅いコピーを返します。
- copy.deepcopy(x[, memo])
- x のディープコピーを返します。
- exception copy.Error
- モジュール固有のエラーのために発生します。
浅いコピーと深いコピーの違いは、複合オブジェクト(リストやクラスインスタンスなどの他のオブジェクトを含むオブジェクト)にのみ関係します。
- 浅いコピーは、新しい複合オブジェクトを作成し、(可能な範囲で)元のオブジェクトにあるオブジェクトへの参照を挿入します。
- ディープコピーは、新しい複合オブジェクトを作成し、再帰的に、元のオブジェクトのコピーを挿入します。
浅いコピー操作では存在しない深いコピー操作には、2つの問題がしばしば存在します。
- 再帰オブジェクト(直接的または間接的に、それ自体への参照を含む複合オブジェクト)は、再帰ループを引き起こす可能性があります。
- ディープコピーはすべてをコピーするため、コピー間で共有することを目的としたデータなど、コピーしすぎる可能性があります。
deepcopy()関数は、次の方法でこれらの問題を回避します。
- 現在のコピーパス中にすでにコピーされたオブジェクトの
memo
ディクショナリを保持します。 と - ユーザー定義クラスがコピー操作またはコピーされたコンポーネントのセットをオーバーライドできるようにします。
このモジュールは、モジュール、メソッド、スタックトレース、スタックフレーム、ファイル、ソケット、ウィンドウ、配列、または同様のタイプのようなタイプをコピーしません。 元のオブジェクトを変更せずに返すことにより、関数とクラスを(浅く深く)「コピー」します。 これは、これらが pickle モジュールによって処理される方法と互換性があります。
dict.copy()を使用して辞書の浅いコピーを作成したり、copied_list = original_list[:]
などのリスト全体のスライスを割り当てることでリストのコピーを作成したりできます。
クラスは、ピクルスを制御するために使用するのと同じインターフェースを使用してコピーを制御できます。 これらのメソッドの詳細については、モジュール pickle の説明を参照してください。 実際、 copy モジュールは、 copyreg モジュールから登録されたpickle関数を使用します。
クラスが独自のコピー実装を定義するために、特別なメソッド__copy__()
および__deepcopy__()
を定義できます。 前者は、浅いコピー操作を実装するために呼び出されます。 追加の引数は渡されません。 後者は、ディープコピー操作を実装するために呼び出されます。 memo
ディクショナリという1つの引数が渡されます。 __deepcopy__()
実装でコンポーネントのディープコピーを作成する必要がある場合は、コンポーネントを最初の引数として、メモディクショナリを2番目の引数として、 deepcopy()関数を呼び出す必要があります。