Pythonでは、オブジェクトのコピーは**浅いコピー(shallow copy)と深いコピー(deep copy)**の2種類があります。浅いコピーは新しいコンテナを作成しますが、入れ子のオブジェクトはコピーされず、同じオブジェクトへの参照が使用されます。深いコピーは再帰的にすべての入れ子のオブジェクトの新しいコピーを作成し、コピーの独立性を確保します。
copyモジュールは、copy()(浅いコピー)とdeepcopy()(深いコピー)というメソッドを提供します:
import copy original = [[1, 2], [3, 4]] shallow = copy.copy(original) deep = copy.deepcopy(original) shallow[0][0] = 99 print(original) # [[99, 2], [3, 4]] ← 元のオブジェクトが変更されました! deep[1][1] = 42 print(original) # [[99, 2], [3, 4]] - 変更されていない
list2 = list1演算子とcopy.copy(list1)を使用した場合の違いは何ですか?
回答: 演算子list2 = list1は同じオブジェクトへの新しい参照を作成します。copy.copy(list1)は浅いコピーを作成し、新しいオブジェクトリストを作成しますが、内部のオブジェクトは同じです。入れ子の構造に対しては浅いコピーでは不十分で、深いコピーが必要です。
物語
REST APIを開発中に、テンプレートからデータが通常の代入(
data = template)でコピーされていました。次のリクエストにより、すべての後続のユーザーに対して「テンプレート」が偶然に変更されました。同じ参照が使用されていたからです。
物語
レポートモジュールでは、
copy.copy()を介してデータがコピーされましたが、構造が入れ子(辞書の中のリスト)であったため、コピーでの変更が元のデータに予期せず反映され、統計にエラーを引き起こしました。
物語
ある銀行のプロジェクトで、
copy.copy()(ではなくdeepcopy())を通じて複雑な入れ子のオブジェクトの不正なコピーが行われ、トランザクションの履歴が失われました。新しい操作が古い操作を上書きしてしまったのは、入れ子の要素が共有されていたためです。