본문 바로가기

python

mutable과 immutable한 객체

일단 파이썬의 자료형은 모두 객체이다.


파이썬 자료형에는 mutable한 객체와 immutable한 객체가 있는데

평소때는 상관없는데 값을 복사할때 골치 아파진다.

 

mutable한 객체를 복사하면 Call by reference

immutable한 객체를 복사하면 Call by value

식으로 복사된다


mutable한 객체

 array, list, set, dic

 immutable한 객체

 int, float, string, tuple, bool

immutable한 객체는 call by value 으로 복사하기 때문에 

아무 생각없이 사용해도 상관이 없다.


mutable한 객체를 다룰 때 특히 문제가 생기는데

>>> a = [1, 2]
>>> b = a
>>> a.append(3)
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]

 mutable한 자료형 list를 복사하면

a만 수정했는데 b도 같이 수정된다.(call by reference)

id() 함수로 각 변수를 확인해보면 잘 알 수 있다.


변수를 직접 대입하지 말고 

copy함수나 리스트인덱싱을 사용하는 방법도 있는데

>>> import copy
>>> a = [1,2]
>>> b = copy.copy(a)
>>> c = a[:]
>>> a.append(3)
>>> a
[1, 2, 3]
>>> b
[1, 2]
>>> c
[1, 2]

해결된것처럼 보이지만 

>>> import copy >>> a=[(1,2),[2,3]] >>> b=copy.copy(a) >>> c=a[:] >>> a[1].append(4) >>> a [(1, 2), [2, 3, 4]] >>> b [(1, 2), [2, 3, 4]] >>> c [(1, 2), [2, 3, 4]]

이 처럼 리스트안에 imutable한 int값이 아닌 mutable한 list가 들어가 있으면 

내부값이 변하면 또 또 내부안에서 call by reference가 발생한다.

위의 경우를 통틀어 얕은 복사라고 하는데(shallow copy)


아예 새로운 객체를 만들기 위해서는 깊은복사(deep copy)가 필요하다. 

>>> import copy
>>> a=[(1,2),[2,3]]
>>> b = copy.deepcopy(a)
>>> a[1].append(4)
>>> a
[(1, 2), [2, 3, 4]]
>>> b
[(1, 2), [2, 3]]

deepcopy함수를 씁시다.


추가로 dic객체를 보자

dic = { key : value , ... }

내가 첨에 파이썬을 배울때 dic자료형의 key값은 리스트는 안된다고 들어봤는데(아마도 점프 투 파이썬 책이였을 듯)

정확하게는 key에는 immutable한 객체만 올 수 있기 때문이다.



결론

  • mutable한 자료형 list, set, dic을 쓸 때 복사에 주의하자
  • 웬만하면 내부에는 immutable한 tuple를 쓰자



'python' 카테고리의 다른 글

클래스 메소드에 인수로 self 주는 이유  (0) 2018.04.28
타입 힌팅(type hinting)  (0) 2018.04.28
(19)번역 api 사용 후기  (0) 2018.04.07
django-tube 튜토리얼 하면서 생긴 오류  (0) 2018.04.04
Tesseract - OCR 연습  (0) 2018.03.23