Deep copy

 

여러가지 복잡한 함수들로 변수가 이동하면서 자주 발생하는 문제가 있는데 바로 데이터 불변성(immutability)과 관련된 것입니다.

1. Mutable object vs Immutable object

객체지향 프로그래밍에서 모든 객체는 상태를 변경할 수 있는지 여부에 따라 2가지로 분류될 수 있습니다.

Mutable object
생성 이후 상태를 변경할 수 있는 객체
e.g. list, dict, set

Immutable object
생성 이후 상태를 변경할 수 없는 객체
e.g. int, float, str, tuple

2. Shallow copy vs Deep copy

객체를 복사하기 위해 다음 2가지 방법을 사용할 수 있습니다.

Shallow copy
객체의 참조를 복사하는 방법으로 원본 객체와 생성된 객체는 동일한 참조(주소값)를 가집니다.

Deep copy
객체의 값을 복사하는 방법으로 원본 객체와 생성된 객체는 다른 참조(주소값)을 가집니다.

3. Python implementation

Python에서 객체를 할당하는 경우 shallow copy를 수행합니다.
따라서, Deep copy를 수행하기 위해선 이를 위한 함수를 명시적으로 사용해야 합니다.
copy.deepcopy()를 통해 deep copy를 수행할 수 있습니다.

특히, str을 가진 dict를 포함하고 있는 dict와 같이 여러 객체들이 중첩되어 있는 경우 내부 객체들까지 완전히 deep copy 하지 않으면 데이터의 불변성이 깨지기 때문에 다음 예제의 결과를 잘 기억해두시기 바랍니다.

from copy import deepcopy as copy


origin = dict(
    data=dict(
        base_date='0'))

dic1 = origin         # shallow copy
dic2 = origin.copy()  # shallow copy on other dictionary
dic3 = dict(origin)   # shallow copy on other dictionary
dic4 = copy(origin)   # deep copy

dic1['data']['base_date'] = '1'
dic2['data']['base_date'] = '2'
dic3['data']['base_date'] = '3'
dic4['data']['base_date'] = '4'

print(id(origin), id(dic1), id(dic2), id(dic3), id(dic4))
print(origin['data']['base_date'], dic1['data']['base_date'], dic2['data']['base_date'], dic3['data']['base_date'], dic4['data']['base_date'])
140412663688480 140412663688480 140412671777760 140412663688880 140413045188400
3 3 3 3 4