파이썬 프로그래밍에서 딕셔너리는 키-값 쌍을 연결하고 데이터를 효율적으로 검색하고 조작할 수 있는 매우 강력한 자료 구조입니다. 사용자 정의 객체를 딕셔너리에 저장하려고 할 때, 중요한 개념은 파이썬의 객체 할당이 실제로는 객체의 깊은 복사라기보다는 참조 할당이라는 것입니다. 즉, 사용자 정의 객체를 딕셔너리에 넣으면 딕셔너리에는 해당 객체의 참조가 저장되고 객체의 새로운 복사본이 저장되는 것이 아닙니다.
사용자 정의 객체 저장의 기본 예제
가정해 봅시다, 간단한 Person
클래스가 있다고 하면:
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 的项,其值是对 __INLINE_CODE_2__BOLD_7p1
BOLD_8__INLINE_CODE_4__의 속성:
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
파이썬에서 딕셔너리로 사용자 정의 객체를 저장할 때는 기본적으로 객체 참조가 저장된다는 점에 유의해야 합니다. 독립적인 상태를 유지해야 하는 경우에는 공유 참조로 인한 예기치 않은 데이터 변경을 피하기 위해 깊은 복사(INLINE_CODE_0)를 사용하십시오.