python

Python mutable 변경 가능, immutable 변경 불가능

Jueuunn7 2024. 9. 23. 02:04

파이썬은 다른 언어들과는 다르게 모든 것들이 객체이다. 이 객체들은 python memory manager에서 관리된다.

이 객체들의 주소는 id 라는 함수를 통해서 알 수 있다.

파이썬엔 mutable 변경 가능, immutable 변경 불가능 객체가 있다.

immutable int, floot, bool, str, tuple
mutable list, set, dic

immutable

>>> a = 100
>>> b = 100
>>> c = 100
>>> print(id(a), id(b), id(c))
4390937440
4390937440
4390937440

위 코드는 각각 다른 변수들에 100이라는 integer 값을 할당해 주더라도 객체의 주소는 다 같은 걸 볼 수 있다.

여기서 python memory manager은 100이라는 값을 heap 메모리 영역에 할당시키고 각 변수들을 해당 heap에 100이라는 값을 참조하게 한다. 

값을 변경하면 200을 heap 메모리 영역에 할당시키고 c라는 변수가 참조하게 한다.

>>> c = 200
>>> print(id(a), id(b), id(c))
4390937440
4390937440
4390940640

 

mutable

list는 변수와는 다르게 자신이 갖고 있는 값이 같더라도 각각 다른 주소를 참조하고 있는것을 알 수 있다.

>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> c = [1, 2, 3]
>>> print(id(a), id(b), id(c))
4371515712
4371517504
4373684864

 

 

각 배열에 0번째 값을 가져와보면 각각 같은 주소를 참조하고 있는걸 볼 수 있다.

>>> print(id(a[0]), id(b[0]), id(c[0]))
4386084608
4386084608
4386084608

 

내부 값은 변경되어도 배열이 참조하는 주소는 변하지 않는다.

>>> a.append(4)
>>> print(id(a), id(b), id(c))
4371515712
4371517504
4373684864

 

이제 다른 변수에 4를 저장하고 a[3] 과 비교해 보면 같은 주소를 참조하고 있다.

>>> var = 4
>>> print(id(var), id(a[3]))
4386084704 
4386084704

 

리스트들은 갖고있는 값이 같든 다르든 상관없이 각각의 고유한 주소를 참조한다. 하지만 다른 리스트들 안에 있는 같은 값들은 변수와 똑같이 같은 주소를 참조하는 것을 볼 수 있다. 이 값은 리스트라고 변수와 다른 데이터를 사용하는 게 아니라 변수와 같은 데이터를 사용한다.

 

tuple

그럼 과연 변경이 불가능한 튜플은 어떻게 동작할까?

튜플도 각각 다른 주소를 참조한다.

>>> a = (1, 2, 3)
>>> b = (1, 2, 3)
>>> print(id(a), id(b))
4372655552
4372718592

 

내부 원소의 같은 값들은 같은 주소를 참조한다.

>>> print(id(a[0]), id(b[0]))
4386084608
4386084608

 

튜플은 사실 변경이 가능하긴 하다. 하지만 이 수정은 정확히 말하면 변경이 아니다.

>>> a += (4, )
>>> print(id(a), id(b))
4372671168 # origin 4372655552
4372718592

이 방식은 우리에겐 튜플에 새로운 값이 추가된것처럼 보일순 있지만 사실 튜플이 수정된 것이 아니라 새로운 객체 하나가 생성되는 것이다.

튜플은 변경 불가능한 객체이기때문에 이런 방식으로 작동한다.

 

튜플의 원소도 int형이며 다른 int형 변수와 같은 주소를 참조한다.

>>> var = 4
>>> print(id(a[3]), id(var))
4386084704 
4386084704

 

 

결론

변수들은 python memory manager에 의해 heap 메모리에 캐싱되어서 같은 값을 갖고 있으면 같은 주소를 참조한다.

리스트는 서로 다른 객체이며 리스트의 요소인 int들은 동일한 값의 int 변수들의 객체를 같이 사용한다. char 형도 똑같다.

튜플도 변경이 가능한 것 같지만 튜플 자체가 변경되지 않고 새로운 튜플 객체가 생긴다.

이처럼 python memory manager은 알아서 효율적으로 메모리를 관리해준다. 

'python' 카테고리의 다른 글

Python - yield  (0) 2024.12.10
Python - 멀티스레드, GIL (Global Interpreter Lock)  (0) 2024.11.25
Python list append, extend, +=  (0) 2024.10.07
Python 잘 쓰는법: 리스트, 딕셔너리  (1) 2024.09.09
Python 다중 상속, super()  (0) 2024.09.02