상세 컨텐츠

본문 제목

Deep, Shallow Copy (2) - Mutable vs Immutable

개발/python-심화(Advanced)

by Matthew0633 2022. 4. 29. 01:58

본문

지난번에는 반복을 활용한 List 생성 2가지 방식에서의 Deep Copy, Shallow Copy 를 비교해보았는데, 이번에는 동일한 관점에서 Mutable객체와 Immutable 객체 간을 비교해보려 한다. deep, shallow copy를 공부하며, 개발에 관련된 개념을 공부할 때의 생각 또는 마음가짐에 대해 크게 배운 점이 있어 이를 마지막 부분에 적어보았다

 

Mutable vs Immutable

앞서서는, 반복을 활용해 List의 원소들을 생성하는 두가지 문법이 각각 Deep copy와 Shallow copy로 생성되는 예를 보았다. 좀 더 나아가서, mutable 객체와 immutable 객체 사이에는 copy 방식에서 어떤 차이가 있는지 살펴보자.

아래는 Mutable한 구조의 한 종류인 List와 Immutable 구조의 하나인 Tuple의 원소를 반복을 통해 복사한 예이다.

tp = (15, 20, 25)
li = [15, 20, 25]

print(tp, id(tp))
print(li, id(li))

tp = tp * 2
li = li * 2

print(tp, id(tp))
print(li, id(li))

tp *= 2
li *= 2

print(tp, id(tp))
print(li, id(li))

"""
Outputs:
(15, 20, 25) 1547800386688
[15, 20, 25] 1547800428800
(15, 20, 25, 15, 20, 25) 1547800004352
[15, 20, 25, 15, 20, 25] 1547800365696
(15, 20, 25, 15, 20, 25, 15, 20, 25, 15, 20, 25) 1547799915824
[15, 20, 25, 15, 20, 25, 15, 20, 25, 15, 20, 25] 1547800365696
"""

먼저, tuple 객체의 경우, 원소 반복을 통해 값을 수정했을 때, 완전히 복사가 되어 새로운 메모리 주소에 저장되는 것을 확인할 수 있다. 즉, 수정이 불가능한 immutable한 성질 때문에, 수정을 희망해도, 값이 다른 객체를 새로이 생성하고 저장하게 된다.

반면, List 객체의 경우 문법에 따라 차이가 있다. li = li * 2 과 같은 문법을 사용할 때는, 같은 변수의 이름에 동일한 값이, 다른 메모리 주소에 할당되는 deep copy가 일어난 것을 볼 수 있다. 그러나, li *= 2 의 문법을 사용했을 때는 mutable한 특성에 어울리게, 이전 메모리 주소에 있는 값이 수정된채로 변수가 가리키고 있는 것을 알 수 있다.

처음 이 개념을 접할 때, 다루는데 비교적 난이도가 낮은 Deep copy를 Shallow copy보다 낫다라는 개념으로 생각을 하고 있었는데, 이는 매우 잘못된 생각이었다. 개발자가 되어, 개발에 대한 고민과 생각을 하기 시작하면서, 프로그래밍 언어에는 어떤 기능 또는 특징을 구현해놓은 이유와 목적이 반드시 존재한다는 믿음을 가지게 되었다. 이러한 관점으로 바라보자면, Deep copy와 Shallow copy는 특정상황에서 각각 더 효율적일 수 있는 개념들이다. 예를 들어, 초심자에게는 단순히 이전 값에 영향을 주지 않는 deep copy를 자주 사용하는 것이 에러발생이나, 디버깅 측면에서 편리할 수 있다. 반면, 만약 자료의 양이 방대하고, 값이 자주 일어나는 상황에서 자료를 다루는 개발자는 아무생각없이 immutable 객체를 사용하거나, mutable 객체를 deep copy와 함께 사용한다면 메모리 효율성이 굉장히 저하될 수 있다. 이러한 상황에서, 더 나은 옵션은 mutable 객체를 shallow copy 방식으로 사용하는 것이 될 수 있다.

관련글 더보기

댓글 영역