미리보기:

파이썬을 사용하다 보면 is와 ==의 차이에 대해 헷갈리는 경우가 많습니다. 일반적으로 ==는 "값이 같은가?"를 비교하고, is는 "같은 객체인가?"를 비교한다고 알려져 있습니다. 하지만 여기서 한 걸음 더 나아가 파이썬의 메모리 관리 방식과 객체 캐싱 전략을 깊이 이해하면 더 신박한 사실을 발견할 수 있습니다.
is: 두 변수가 동일한 객체를 가리키는지 비교합니다.
- 리스트 [1, 2, 3]은 x와 y 각각 별도의 메모리 공간에 생성되었기 때문에 x is y는 False입니다.
하지만 정수형을 비교할 때는 조금 다른 결과가 나옵니다.
a = 256
b = 256
print(a == b) # True
print(a is b) # True
c = 257
d = 257
print(c == d) # True
print(c is d) # False
왜 a is b는 True인데 c is d는 False일까요?
이제부터 파이썬의 메모리 최적화 전략을 자세히 살펴보겠습니다.
파이썬의 작은 정수 캐싱 (Integer Interning)
파이썬은 -5에서 256까지의 정수를 미리 캐싱하여 같은 객체를 재사용합니다.
x = 256
y = 256
print(x is y) # True
x = 257
y = 257
print(x is y) # False
이유
- 파이썬은 메모리 최적화를 위해 -5 ~ 256 범위의 정수를 미리 캐싱합니다.
- 따라서 x = 256과 y = 256은 같은 메모리 주소를 참조합니다.
- 하지만 257과 같은 큰 숫자는 새로운 객체로 생성되므로 x is y가 False가 됩니다.
이 메커니즘을 확인하려면 id() 함수를 사용하여 객체의 메모리 주소를 출력해 볼 수 있습니다.
print(id(256), id(256)) # 같은 주소
print(id(257), id(257)) # 다른 주소
문자열 캐싱
정수뿐만 아니라 문자열도 캐싱됩니다. 다만 모든 문자열이 캐싱되는 것은 아니며, 다음과 같은 경우에만 적용됩니다.
s1 = "hello"
s2 = "hello"
print(s1 is s2) # True
s3 = "hello world! this is a long string"
s4 = "hello world! this is a long string"
print(s3 is s4) # False (일반적으로)
문자열 규칙:
- 짧고 자주 사용되는 문자열 (hello, Python 등)은 캐싱됩니다.
- 공백이 없는 문자열은 캐싱될 가능성이 높습니다.
- 긴 문자열은 새로운 객체로 할당될 가능성이 높습니다.
파이썬의 sys.intern()을 사용하면 수동으로 문자열을 캐싱할 수도 있습니다.
import sys
s1 = sys.intern("this is a very long string")
s2 = sys.intern("this is a very long string")
print(s1 is s2) # True
is와 ==를 언제 사용해야 할까?
==을 사용해야 할 때:
- 값을 비교할 때 (예: 리스트, 딕셔너리, 문자열 비교)
- if user_input == "yes": (사용자가 입력한 값 비교)
is를 사용해야 할 때:
- None을 비교할 때 (if variable is None:)
- 싱글턴 객체를 비교할 때 (if my_object is some_global_instance:)
- 메모리 상에서 객체의 동일성을 확인할 때
x = None
if x is None:
print("x is None")
'Too_Much_Information' 카테고리의 다른 글
In Pandas | ValueError: The truth value of a Series is ambiguous. (0) | 2025.03.18 |
---|---|
TMI _ Jupyter Notebook에서 print() 없이 출력이 가능한 이유 (0) | 2025.02.06 |