탐구 생활/Python

Python 가변 객체와 불변 객체

개발프로브 2024. 11. 17. 15:23

Python의 가변 객체와 불변 객체

Python에서 객체는 가변 객체(Mutable Objects)불변 객체(Immutable Objects)로 나눌 수 있다. 이 두 가지는 객체의 값을 변경할 수 있는지 여부에 따라 구분되며, 메모리 관리와 성능에 중요한 영향을 미친다.

 

1. 가변 객체 (Mutable Objects)

특징

  • 값(내용)을 변경할 수 있음.
  • 동일한 객체를 참조하는 변수는 변경 사항을 공유.
  • 대표적인 가변 객체:
    • list 리스트
    • dict 딕셔너리
    • set 세트
    • 사용자 정의 클래스 객체

예제

x = [1, 2, 3]  # 리스트 객체 생성
y = x           # x와 y는 같은 객체를 참조
x.append(4)     # x의 값을 변경

print(x)  # 출력: [1, 2, 3, 4]
print(y)  # 출력: [1, 2, 3, 4] (y도 동일한 객체를 참조하므로 변경됨)
print(x is y)  # 출력: True (x와 y는 같은 객체)

2. 불변 객체 (Immutable Objects)

특징

  • 값(내용)을 변경할 수 없음.
  • 새로운 값을 할당하면 새로운 객체가 생성.
  • 동일한 값을 가진 불변 객체는 객체를 재사용할 수 있음 (Python 내부 최적화).
  • 대표적인 불변 객체:
    • int 정수
    • float 실수
    • str 문자열
    • tuple 튜플

예제

a = 10          # 정수 객체 생성
b = 10          # 동일한 값을 참조 (Python 내부 캐싱)
c = int(10)     # 동일한 값을 참조

print(a is b)   # 출력: True (a와 b는 같은 객체를 참조)
print(a is c)   # 출력: True (Python은 동일한 값을 재사용)
print(a == c)   # 출력: True (값이 동일)

x = "hello"
y = "hello"
z = "".join(["h", "e", "l", "l", "o"])  # 새로운 문자열 생성

print(x is y)   # 출력: True (문자열 캐싱으로 인해 같은 객체를 참조)
print(x is z)   # 출력: False (z는 새로 생성된 객체)
print(x == z)   # 출력: True (값은 동일)

3. is==의 차이

이미 위의 예제에서 계속해서 사용했으므로 is 와 == 가 무엇이 다른지 궁금할 수 있다.

is (식별자 비교)

  • 두 변수가 같은 객체(메모리 주소)를 참조하는지 비교.
  • 불변 객체와 가변 객체 모두 동일하게 동작.
x = [1, 2, 3]
y = x
z = [1, 2, 3]

print(x is y)  # 출력: True (x와 y는 같은 객체)
print(x is z)  # 출력: False (x와 z는 다른 객체)

# 변수가 참조하는 메모리 값은 id() 로 확인할 수 있다.

print(id(x)) # 1231 (예를들어...)
print(id(y)) # 1231
print(id(z)) # 4412

== (값 비교)

  • 두 객체의 값(내용)이 같은지 비교.
  • Python은 기본적으로 __eq__ 메서드를 호출하여 값 비교를 수행.
x = [1, 2, 3]
z = [1, 2, 3]

print(x == z)  # 출력: True (리스트의 값이 동일)

4. 가변 객체와 불변 객체의 차이 요약

특징 가변 객체 (Mutable) 불변 객체 (Immutable)
값 변경 가능 여부 변경 가능 변경 불가능
객체 재사용 여부 동일 값이어도 새로운 객체 생성 동일 값일 경우 객체 재사용 가능
대표적인 예 list, dict, set int, str, tuple

5. 가변 객체와 불변 객체의 장단점

  가변 객체 불변 객체
장점 - 값을 직접 변경할 수 있으므로 메모리 사용량 줄일 수 있음.
- 리스트나 딕셔너리처럼 유연하게 수정이 필요한 경우 적합.
- 값이 변경되지 않으므로 안정성이 보장됨.
- 해시 가능하여 딕셔너리의 키나 set의 요소로 사용 가능.
단점 - 동일한 객체를 참조하는 변수들 간의 변경 사항이 공유되어 예상치 못한 부작용(side effect)을 초래할 수 있음. - 값을 변경하려면 새로운 객체를 생성해야 하므로 메모리 사용량 증가 가능.

 


6. 가변 객체와 불변 객체의 활용

가변 객체 활용

  • 데이터의 값을 자주 수정해야 하는 경우 (예: 리스트에서 데이터를 추가/삭제).
  • 상태를 유지하면서 동적으로 변경이 필요한 경우.

불변 객체 활용

  • 딕셔너리의 키 또는 집합의 요소로 사용해야 하는 경우 (해시 가능 필요).
  • 데이터가 변경되지 않아야 하거나 안정성이 중요한 경우.

Python의 가변 객체와 불변 객체를 이해하면 메모리 사용과 성능을 최적화할 수 있으며, 코드의 안정성을 높일 수 있습니다. 가변 객체와 불변 객체를 적절히 활용하여 효율적이고 Pythonic한 코드를 작성해보세요!