8.17. copy — 浅いコピーおよび深いコピー操作 — Python 2.7ja1 documentation

### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.7ja1 documentation »
- Python 標準ライブラリ »
- 8. データ型 »

# 8.17. `copy` — 浅いコピーおよび深いコピー操作

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

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

`copy.` `copy`(x)

  x の浅い (shallow) コピーを返します。

`copy.` `deepcopy`(x)

  x の深い (deep) コピーを返します。

exception `copy.` `error`

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

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

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

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

- 再帰的なオブジェクト (直接、間接に関わらず、自分自身に対する参照を持つ複合オブジェクト) は再帰ループを引き起こします。
- 深いコピーでは、 何もかも をコピーするため、例えば複数のコピー間で共有されるべき管理データ構造までも、余分にコピーしてしまいます。

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

- 現在のコピー過程ですでにコピーされたオブジェクトからなる、 “メモ” 辞書を保持します; かつ
- ユーザ定義のクラスでコピー操作やコピーされる内容の集合を上書きできるようにします。

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

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

バージョン 2.5 で変更: 関数コピーの追加.

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

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

参考

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

### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python 2.7ja1 documentation »
- Python 標準ライブラリ »
- 8. データ型 »