Python辞書にカスタムオブジェクトを格納する際の、参照とdeepcopyの重要性

Pythonプログラミングにおいて、辞書は非常に強力なデータ構造であり、キーと値を関連付けて、効率的にデータを検索および操作できます。辞書にカスタムオブジェクトを格納しようとすると、重要な概念に遭遇します。Pythonにおけるオブジェクトの代入は、実際にはオブジェクト自体の深いコピーではなく、参照による代入です。つまり、カスタムオブジェクトを辞書に格納する場合、辞書にはそのオブジェクトへの参照が格納され、オブジェクトの新しいコピーではありません。

カスタムオブジェクトの保存に関する基本的な例

仮に、単純な INLINE_CODE_0 クラスがあるとします。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 创建一个 Person 对象
p1 = Person("Alice", 30)

# 将对象存储到字典中
people_dict = {}
people_dict["alice"] = p1

この例では、INLINE_CODE_0 字典现在包含一个键为 __INLINE_CODE_1__BOLD_6PersonBOLD_7p1 对象的引用。如果我们修改 p1 の属性:

p1.age = 31

辞書を通してオブジェクトにアクセスすると、その年齢も更新されていることがわかります。

print(people_dict["alice"].age)  # 输出:31

辞書に格納されているのは、Personオブジェクトの独立したコピーではなく、同じメモリのアドレスを指す参照です。

深いコピーと浅いコピーの違い

ネストされたデータ構造やカスタムオブジェクトを扱う場合、この参照の挙動により予期せぬ結果が生じる可能性がある。例えば、カスタムオブジェクトに可変型の属性(リストや別のカスタムオブジェクトなど)が含まれている場合、そのようなオブジェクトを直接辞書に格納し、それを変更すると、辞書を通して取得したオブジェクトも影響を受ける。

class Address:
    def __init__(self, street, city):
        self.street = street
        self.city = city

class Person:
    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address

address = Address("Main St.", "Springfield")
p1 = Person("Bob", 40, address)
people_dict["bob"] = p1

# 修改原始地址对象
address.city = "Shelbyville"

# 字典中的人的地址也变了
print(people_dict["bob"].address.city)  # 输出:Shelbyville

申し訳ありませんが、翻訳する中国語のテキストが提供されていません。テキストを提供してください。

このような共有状態がもたらす問題を避けるために、辞書にオブジェクトの完全なコピーを格納し、参照ではなく、ということが必要な場合があります。Python は、この目的を達成するための copy() 関数を提供します。

import copy

# 使用深拷贝存储对象
people_dict["bob_deepcopy"] = copy.deepcopy(p1)

# 此时即使修改原始地址对象,深拷贝的对象不会受影响
address.city = "Capital City"
print(people_dict["bob"].address.city)  # 输出:Capital City
print(people_dict["bob_deepcopy"].address.city)  # 输出:Shelbyville

要するに、Pythonで辞書を使ってカスタムオブジェクトを保存する場合、デフォルトではオブジェクトへの参照が格納されることに注意してください。独立した状態を維持する必要がある場合は、予期せぬデータ変更を防ぐために、深コピーを使用してください。

Licensed under CC BY-NC-SA 4.0
最終更新 2025年05月28日 09:47
金融ITプログラマーのいじくり回しと日常のつぶやき
Hugo で構築されています。
テーマ StackJimmy によって設計されています。