mutable / immutable

김지용·2022년 6월 7일
1

mutable과 immutable

파이썬은 모든 것이 객체(object)인데, 그 속성이 mutable(값이 변한다) 과 immutable로 구분된다. / 그런 점에서 장고는 객체지향적이라고 말할 수 있는 것 같다.

Immutable : 숫자(number), 문자열(string), 튜플(tuple)

Mutable : 리스트(list), 딕셔너리(dictionary), NumPy의 배열(ndarray)

즉, 숫자, 문자열, 튜플은 값을 변경하지 못하고, 리스트와 딕셔너리는 변경할 수 있다는 뜻이다.

x = 1
y = x
y += 3
x
1
y
4

위에서 두번째 라인까지는 1이라는 동일한 객체를 x와 y가 가르키고 있다. 세번째에서 y의 값을 변경하는 순간 y는 4를, x는 1을 가르키게 된다. C/C++같은 언어 관점에서 보면 y=x가 실행하는 순간 값을 복사하는 것으로 이해할 수 있다. 조금 다른 점은 y=x가 호출되는 시점에는 동일한 객체를 가르키다가 immutable 타입인 y를 변경했을 때 변경된다는 점이다. id(obj)를 이용하면 보다 자세하게 이해할 수 있다.

x = 1
y = x
id(1)
140706521527120
id(x)
140706521527120
id(y)
140706521527120
y += 3
id(y)
140706521527216

id(obj)는 객체의 유일한 숫자를 리턴하는데 포인터로 이해해도 무방하다.

다음은 다른 immutable 타입인 문자열(string)과 튜플( tuple)의 예이다.

x = 'abcd'
y = x
y += 'e'
x
abcd
y
abcde
x = (1,2,3)
y = x
y += (4,)
x
(1,2,3)
y
(1,2,3,4)

Mutable 타입은 쓰기가 가능한 컨테이너로 이해할 수 있다. 앞서에서 튜플(tuple)은 읽기만 가능한 컨터이너이기 때문에 immutable 이다. 다음은 리스트에 적용한 예이다.

x = [1,2,3]
y = x
y += [4,]
x
[1,2,3,4]
y
[1,2,3,4]

위에서 두번째 줄까지 실행하면 x, y는 모두 [1,2,3]을 가르키게 된다. 이후 y를 변경하면 x 역시도 변경되게 된다. 즉, C/C++ 관점에서 보면 포인터 연산 또는 레프런스 변수로 선언한 것과 유사함을 알 수 있다. 쓰기가 가능한 컨테이너는 mutable 이므로 shallow copy 가 되는 것으로 이해할 수도 있다.

복사

Python에서 immutable 자료형(숫자, 문자열, 튜플)은 직접 값이 변경되는 deep copy로 이해할 수 있다. 반면에 mutable 자료형(즉, 쓰기가 가능한 컨테이너)는 shallow copy(내부적으로 포인터만 복사)를 적용된다.

a = [1,2,3]    
b = a          # b와 a는 같은 값을 가르킴(shallow copy)
b is a 
True
b[1] = 10      # a = b = [10,11]
a = [5, 11]   # a = [5,11] 이도록 새로 지정함, b와 연결이 끊어짐.
b is a
False

실제 값까지 복사(deep copy)하기 위해서는 object.copy() 를 사용해야 한다.

a = [1,2,3]
b = a.copy()   
b is a
False
b == a 
True

위에서 is==를 통한 결과값이 다른 것을 알 수 있다. is는 내부적으로 유지하는 포인터값을 비교하고, ==는 list를 구성하는 성분을 비교한다.

핵심 키워드 깊은 복사

profile
김죵입니당 ^^

0개의 댓글