본문 바로가기

Language/Python

Python 07 - 불변 객체와 가변객체 ( 메모리 자원 )

 파이썬에서 불변 객체와 가변객체는 메모리 자원 관리 측면에서 매우 중요한 개념이다.

 

불변 객체란 말 그대로 변하지 않는 객체를 의미한다.

 

문자열, 숫자, tuple 객체가 불변 객체인데 객체에 메모리 공간이 한 번 할당되면 그 크기는 더이상 변하지 않는다는 특징을 가지고 있다. 

 

반대로 가변 객체는 변할 수 있는 객체이다.

 

list, set, dictionary 객체가 가변 객체이며 이 객체들은 메모리 공간이 할당 되어도 그 크기가 변할 수 있는 특징을 가지고 있다.

 

객체마다 이렇게 다른 특징을 가지고 있기 때문에 코드를 짤 때 상황에 맞춰 올바르게 사용해야 한다. 특히 함수와 클래스와 같은 문법과 결합되면 굉장히 복잡해질 수 있다.

 

간단한 예시로 불변 객체를 변수가 참조하는 방식과 가변객체를 변수가 참조하는 방식에 대해 알아보자.

 

먼저 불변 객체를 보자.

 

a = 100 

a = 100 + 5 

 

이 경우는 변수 a가 불변 객체인 숫자형 객체 100을 참조하고 있다. 즉 메모리에 100이라는 객체가 올라와 있는 것이다. 

그러다 a = 100 + 5 코드가 진행되면 a라는 변수는 105라는 새로운 객체를 참조한다. 숫자형 객체는 불변이라 100이라는 객체에 값이 더해지는 것이 아니라 105라는 새로운 객체가 생기며 그 객체를 변수a가 참조한다.

 

가변 객체의 경우도 살펴보자.

 

c = [1,2,3] 

d = [1,2,3]

c.append(4)

 

이 경우는 변수 c와 d가 가변 객체인 리스트 [1,2,3]을 참조하고 있다. 즉 메모리에 [1,2,3]의 크기에 맞는 공간이 할당되고 객체가 올라와 있는 것이다. 이 경우에 c와 d의 값의 주소를 비교해보면 같은 주소가 나올 것이다. 또 append() 매서드를 이용해서 c 리스트에 값을 추가하여도 여전히 c는 같은 주소를 가지고 있다. 왜나하면 c는 가변 객체이기 때문에 새로운 객체가 생성되는 것이 아니라 기존에 [1,2,3]이 할당된 메모리에서 조금 더 크기를 할당 받아 저장되기 때문이다. 이와 같은 방법을 '동적 배열 할당'이라 한다.

 

가변 객체와 불변 객체는 위와 같은 특징을 가지고 있어 for문과 같이 반복문을 사용할 때는 주의해야한다. 

 

예를 들어 for문 안에서 불변 객체인 문자열을 계속해서 생성하는 코드가 있다면 for문이 실행되는 동안 메모리 공간을 많이 차지하여 성능 면에서 떨어질 확률이 존재한다. 문자열이아니라 리스트를 쓰는 방법을 이용하면 처음 가리키고 있던 객체의 메모리 공간을 조금씩 확장해가며 사용하기에 오히려 좋을 것이다.

 

파이썬의 변수가 불변 객체와 가변 객체를 어떻게 참조하는지에 대해 알아보았다. 이에 추가적으로 중요한 내용이 더 있다.

 

대표적으로 두가지 경우를 살펴볼 예정이다. 하나는 지역변수와 전역변수, 다른 하나는 가변객체와 불변객체의 매서드의 반환값이다.