[PYTHON] 가변객체와 불변객체는 무슨 말일까?

x = [1, 2, 3]
y = x
print(x is y)
# True
x += [4, 5]
print(x is y)
# True
print(x)
print(y)
#[1, 2, 3, 4, 5]
#[1, 2, 3, 4, 5]
가변객체는 무엇이고 불변객체는 무엇일까?
우선 이를 알아보기전에 가변객체, 불변객체에서 공통된 단어, 객체(Object)부터 살펴볼 필요가 있다.
파이썬에서 객체 단위로 메모리 정보를 관리하게 된다.
이러한 객체들중 정보를 수정시킬수 있는 것이 가변객체
이러한 객체들중 정보를 수정시킬수 없는 것이 불변객체라고 말한다.
| 가변 | list , set, dict |
| 불변 | int, float, bool, tuple, string, unicode |
우선 list 와 tuple의 예시를 보며 살펴보자.
List
list = [1, 2, 3, 4]
print(list)
# [1, 2, 3, 4]
list[1] = 222
print(list)
# [1, 222, 3, 4]
Tuple
tuple = (1, 2, 3, 4)
print(tuple)
# (1, 2, 3, 4)
tuple[1] = 222
"""
Traceback (most recent call last):
File "main.py", line 5, in <module>
immutable_tuple[1] = 222
TypeError: 'tuple' object does not support item assignment
list는 기존 값 2를 222로 변경할 수 있지만, tuple은 불변객체이기 때문에 오류가 난다.
여기서 객체란 모든 데이터 타입 즉, 데이터 종류를 말하는데 이러한 객체는 3가지 특징을 가진다.
Value(값) / Type(유형) /id(정체성=메모리위치)이 그것이다
1. Value(값) : 메모리에 기록된 내용 -> 가변객체값은 변할 수 있음. 불변객체는 변할 수 없음
2. Type(유형) : type() 함수를 통해 알 수 있음 (int 인지 float인지 등등)
3. id(정체성) : 정체성보단 메모리위치에 대한 좌표로 이해하면 쉬울 듯하다.
불변객체 예시
x = 'test1'
print(x)
x = x + 'test2'
print(x)
# test1
# test1 test2
x = 'test1'
print(id(x))
# 140450185151280
x += 'test2'
print(id(x))
# 140450185152880
test1 id값과 test2 id값을 보게 되면 서로 다른 것을 확인할 수 있다.
즉, test1과 test1 test2의 메모리 위치가 바뀐 것을 의미하는데, 이는 test1이 변경된 것이 아닌 새로운 object를 생성한 것이다.
기존에 존재했던 object 위치에서 test2가 추가되면서 새로운 object를 생성하고 그 위치에 새로 저장한 것이다.
int, str 등등 불변객체는 이미 메모리 위에 있는 value값을 변경할 수 없다.
가변객체 예시
x = [1, 2, 3]
y = x
print(x is y)
# True
x += [4, 5]
print(x is y)
# True
print(x)
print(y)
#[1, 2, 3, 4, 5]
#[1, 2, 3, 4, 5]
x는 리스트 형태로 1,2,3d을 넣고 y도 같은 값으로 세팅해놓았다.
이때 x에 4,5 값을 추가로 넣게 되면 x값이 수정됨에 따라 y값도 수정됨을 확인할 수 있다.
따라서 가변객체( 현재 이글에서는 리스트)는 메모리위치를 변경하지 않고 값만을 수정할 수 있다는 것이다.
그렇다면 왜 중요한가?
불변객채는 새로운 object를 생성하고 새로운 메모리 공간을 할당해줘야하기 때문에 메모리 누수 현상이 일어날 가능성이 높다. 매번 메모리의 빈공간을 찾아야하는등 연산에 있어 가변객체에 비해 비효율적이다.
따라서 프로그램이 커지고 코드가 복잡해질 수록 성능을 저하시킬 수 있기때문에
Core라고 생각하는 부분은 불변객체로 설정하고
위성이라고 생각되는 부분은 가변객체로 설정하는 것이 좋은 선택이다.
또한 불변객체는 그 값이 변하지 않아 신뢰도가 높다는 것도 참고하여 사용하는 것이 좋다.