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