Pythonでオブジェクトのコピーとディープコピーを理解する

この記事では、Pythonでオブジェクトのコピーとディープコピーについて詳しく解説します。具体的なコード例とその解説、応用例を含めています。

目次

はじめに

Pythonにおいてオブジェクトのコピーは、多くの場面で避けては通れないテーマです。しかし、単純に`=(代入)`を使用すると、オブジェクトそのものではなく参照がコピーされるため、思わぬバグを引き起こす可能性があります。

浅いコピー(Shallow Copy)とは

Pythonにおいて、一次元のリストや辞書などの単純なオブジェクトは、`copy` モジュールの `copy()` 関数またはスライス記法などでコピーすることができます。

浅いコピーの基本的な方法

最も簡単な例として、リストのコピーを考えます。

import copy

original_list = [1, 2, 3]
copied_list = copy.copy(original_list)

# または
copied_list = original_list[:]

print(copied_list)  # 出力:[1, 2, 3]

このようにして作成した `copied_list` は、`original_list` の浅いコピーです。これは元のリスト内のオブジェクト自体は参照されるため、元のリストが持つサブオブジェクト(ネストされたオブジェクト)が変更されると、コピーも影響を受けます。

深いコピー(Deep Copy)とは

`copy` モジュールの `deepcopy()` 関数を使うことで、ネストされたオブジェクトまで新しいオブジェクトとしてコピーが可能です。

深いコピーの基本的な方法

ネストされたリストをコピーする例です。

import copy

original_list = [1, [2, 3], 4]
deep_copied_list = copy.deepcopy(original_list)

print(deep_copied_list)  # 出力:[1, [2, 3], 4]

応用例

オブジェクトのカスタムコピー

`__copy__()` と `__deepcopy__()` メソッドをクラス内に定義することで、カスタムなコピー動作を実現することができます。

import copy

class MyClass:
    def __init__(self, value):
        self.value = value

    def __copy__(self):
        return MyClass(self.value * 2)

    def __deepcopy__(self, memo):
        return MyClass(self.value * 3)

obj = MyClass(10)
shallow_copied_obj = copy.copy(obj)
deep_copied_obj = copy.deepcopy(obj)

print(shallow_copied_obj.value)  # 出力:20
print(deep_copied_obj.value)  # 出力:30

不変オブジェクトとコピー

文字列やタプルなどの不変オブジェクトの場合、通常のコピーと深いコピーは同じ結果となります。

immutable_obj = (1, 2, 3)
copied_obj = copy.copy(immutable_obj)
deep_copied_obj = copy.deepcopy(immutable_obj)

print(copied_obj is immutable_obj)  # 出力:True
print(deep_copied_obj is immutable_obj)  # 出力:True

複数の参照を持つオブジェクトのコピー

1つのオブジェクトが複数の場所で参照されている場合、深いコピーはその関連も保持します。

lst1 = [1, 2, 3]
lst2 = [lst1, 4, 5]

deep_copied_lst2 = copy.deepcopy(lst2)
deep_copied_lst2[0][0] = 'changed'

print(deep_copied_lst2)  # 出力:[['changed', 2, 3], 4, 5]
print(lst2)  # 出力:[[1, 2, 3], 4, 5]

まとめ

Pythonでのオブジェクトのコピーには注意が必要であり、状況に応じて浅いコピーと深いコピーを選択する必要が

あります。また、カスタムオブジェクトで独自のコピー動作を実装することも可能です。

コメント

コメントする

目次