반응형

파이썬에서 immutable과 mutable의 차이를 이해해보자.

 

1. 아래의 간단한 코드를 실행해보자.

x = 1
y = x
z = y

x = 2

print(x, y, z)

결과:

2 1 1

x만 출력값이 바뀌었다.

 

2. 아래의 다른 코드도 실행해보자.

x = [1, 2]
y = x
z = y

x.append(3)

print(x, y, z)

결과:

[1, 2, 3] [1, 2, 3] [1, 2, 3]

x, y, z 모두 출력값이 동일하다.

 

이런 차이가 발생하는 이유는 파이썬에서의 변수 할당 방식과 데이터의 변경 가능성(mutability) 때문이다.

 

1. 불변 객체 (Immutable Objects, 예: 정수)

첫번째 예제에서:

x = 1
y = x
z = y

x = 2

print(x, y, z)

 

  • 정수는 immutable 객체이다. y = x를 실행하면, y는 x가 가리키는 값(1)을 복사받는다.
  • x = 2를 실행하면, x는 새로 생성된 정수 객체 2를 가리키게 된다. 그러나 y와 z는 여전히 원래 정수 객체 1을 가리키고 있기 때문에 값이 바뀌지 않는다.

 

2. 가변 객체 (Mutable Objects, 예: list)

두번째 예제에서:

 

x = [1, 2]
y = x
z = y

x.append(3)

print(x, y, z)

 

  • List는 mutable 객체로, 값을 변경할 수 있다.
  • y = x를 실행하면, y와 z는 모두 x가 가리키는 동일한 리스트 객체를 참조(point to)하게 된다.
  • x.append(3)을 실행하면, list 객체 자체가 변경된다. 이 객체를 참조하는 모든 변수(x, y, z)가 동일한 list를 가리키고 있기 때문에 변경된 결과를 모두 동일하게 보여준다.

 

요약

  • 불변 객체(Immutable): 정수, 문자열, tuple 등. 한 변수에 값을 재할당해도 다른 변수에 영향을 주지 않음.
  • 가변 객체(Mutable): list, dict, set 등. 객체 자체를 수정하면 이를 참조하는 모든 변수가 영향을 받음.

 

 

그렇다면 파이썬에서 immutable과 mutable을 구분한 이유는?

 

1. 효율성 (Efficiency)

  • immutable 객체는 메모리 재활용이 가능하다.
    • 예를 들어, 정수 1은 프로그램 전역에서 자주 사용되므로, 하나의 정수 객체를 여러 변수가 공유할 수 있다. 새로 객체를 만들지 않아도 되므로 메모리 사용량이 줄어들고, 성능이 최적화된다.
    • 문자열 또한 불변이기 때문에, 동일한 문자열은 메모리에 한 번만 저장되고 여러 곳에서 재사용된다(문자열 캐싱).
a = "hello"
b = "hello"
print(a is b)  # True (a와 b는 같은 객체를 가리킴)

 

2. 안전성 (Safety)

  • immutable 객체는 값이 변하지 않기 때문에 데이터의 일관성이 유지된다.
    • 예를 들어 불변 객체는 함수의 인자로 전달되더라도 수정되지 않으므로, 원래 데이터가 의도치 않게 바뀌는 것을 방지할 수 있다.
    • 이는 특히 다중 스레드 환경에서 중요하다. 여러 스레드가 동일한 데이터를 참조하더라도 불변 객체라면 수정할 수 없으므로 동기화 문제를 피할 수 있다.
def add_exclamation(s):
    s += "!"  # 새 문자열 객체를 만듦
    return s

original = "hello"
new_string = add_exclamation(original)
print(original)  # "hello" (원본은 변경되지 않음)

 

3. 유연성 (Flexibility)

  • mutable 객체는 데이터의 동적인 수정이 필요할 때 유용하다.
    • mutable 객체를 사용하면, 대규모 데이터를 다룰 때 효율적으로 데이터를 추가, 삭제, 변경할 수 있다.
    • immutable 객체를 사용할 경우, 데이터를 변경할 때마다 새로운 객체를 만들어야 하므로 성능에 부담이 된다.
# mutable 객체: list
lst = [1, 2]
lst.append(3)  # 원래 list를 수정
print(lst)  # [1, 2, 3]

 

4. 사용자의 의도 표현

  • immutable과 mutable 객체를 나누는 것은 개발자가 의도를 명확히 표현할 수 있게 한다.
    • 데이터를 변경할 필요가 없다면 immutable 객체를 사용해 수정이 불가능한 데이터를 만들고, 변경 가능해야 하는 경우에는 mutable 객체를 사용해 유연하게 처리할 수 있다.

 

결론: 왜 나뉘었는가?

불변과 가변의 구분은 파이썬의 설계 철학에 기반한 것이다.

  • immutable 객체는 데이터의 안정성과 효율성을 제공하며, 변경이 불필요한 데이터를 안전하게 공유할 수 있게 한다.
  • mutable 객체는 데이터 변경의 유연성을 제공하여 다양한 작업에서의 높은 성능과 편의성을 제공한다.

결국, 프로그래밍에서 다양한 요구를 충족시키기 위해 이러한 설계가 필요했던 것.

반응형

+ Recent posts