
파이썬을 학습하며 가장 먼저 접하게 되는 내장 함수 중 하나가 바로 id()입니다. 입문자들은 흔히 이 함수가 단순히 "객체의 고유 번호"를 알려준다고 배우지만, CPython의 내부 구조를 깊이 있게 들여다보면 이 숫자 속에는 파이썬의 메모리 관리 철학과 객체 지향의 본질이 숨어 있습니다. 오늘은 파이썬 전문가의 시각에서 id() 함수가 반환하는 값의 실제 의미와 실무에서 발생할 수 있는 독특한 현상들을 심층적으로 분석해 보겠습니다.
1. id() 함수가 반환하는 값의 본질: 메모리 주소
파이썬 공식 문서에 따르면, id() 함수는 객체의 '아이덴티티(Identity)'를 정수로 반환합니다. 이 값은 객체의 생명 주기 동안 유일하고 변하지 않음이 보장됩니다. 하지만 여기서 중요한 점은 파이썬 구현체(Implementation)에 따라 그 의미가 달라진다는 것입니다.
- CPython: 우리가 흔히 사용하는 표준 파이썬입니다. 여기서
id()는 객체가 저장된 메모리의 실제 가상 메모리 주소를 직접 반환합니다. - Jython / IronPython: 자바 가상 머신(JVM)이나 .NET 환경에서 실행되는 구현체에서는 메모리 주소가 아닌 논리적인 시퀀스 번호일 수 있습니다.
따라서 CPython을 사용 중이라면 id(obj)를 통해 해당 객체가 RAM의 어느 위치에 존재하는지 숫자 형태로 확인할 수 있는 셈입니다.
2. 객체 비교의 핵심: 'is' 연산자와 id()의 관계
파이썬에서 두 객체가 같은지 확인할 때 ==와 is를 사용합니다. 이들의 차이를 명확히 이해하는 것이 버그 없는 코딩의 시작입니다.
표: == 연산자 vs is 연산자 비교
| 비교 항목 | == (Equality) | is (Identity) |
|---|---|---|
| 검사 대상 | 객체의 값 (Value) | 객체의 정체성 (Memory Address) |
| 내부 동작 | __eq__() 메서드 호출 |
id(a) == id(b) 결과와 동일 |
| 사용 목적 | 두 데이터가 같은 내용인지 확인 | 두 변수가 완전히 동일한 객체를 가리키는지 확인 |
| 속도 | 상대적으로 느림 (오버로딩 가능) | 매우 빠름 (주소값 단순 비교) |
3. 주의해야 할 현상: Caching과 Reuse
파이썬은 효율적인 메모리 관리를 위해 Integer Interning과 같은 기법을 사용합니다. 이로 인해 개발자의 직관과 다른 id() 결과가 나올 수 있습니다.
정수 인터닝 (Small Integer Caching)
CPython은 -5부터 256까지의 정수를 미리 메모리에 할당해 두고 재사용합니다. 즉, 이 범위 내의 숫자는 어디서 생성하든 id() 값이 동일합니다.
메모리 재사용 (Memory Reuse)
객체가 소멸(Reference Count가 0이 됨)되면, 그 객체가 점유하던 메모리 주소는 비워집니다. 이후 새로운 객체가 생성될 때 방금 비워진 주소를 그대로 할당받을 수 있습니다. 이 때문에 서로 다른 시점에 생성된 객체가 우연히 같은 id()를 가질 수 있음을 유의해야 합니다.
4. Sample Example: 실전 코드로 보는 id()의 활용
아래 예제는 변수가 가리키는 객체의 변화와 인터닝 현상을 보여줍니다.
# Case 1: 작은 정수 인터닝 (256 이하)
a = 100
b = 100
print(f"a id: {id(a)}, b id: {id(b)}")
print(f"a is b: {a is b}") # True (메모리 주소 동일)
# Case 2: 큰 정수 (범위 밖)
x = 1000
y = 1000
print(f"x id: {id(x)}, y id: {id(y)}")
print(f"x is y: {x is y}") # False (서로 다른 주소)
# Case 3: 리스트 (가변 객체)
list1 = [1, 2, 3]
list2 = [1, 2, 3]
print(f"list1 is list2: {list1 is list2}") # False (값이 같아도 객체는 별개)
5. 결론: id()를 대하는 개발자의 자세
id() 함수는 단순히 숫자를 출력하는 도구가 아니라, 파이썬이 객체를 어떻게 관리하는지 보여주는 창(Window)입니다. 실무에서는 객체의 상태가 변해도 정체성이 유지되는지 확인하거나, 싱글톤 패턴(Singleton Pattern) 구현 여부를 검증할 때 매우 유용하게 사용됩니다. 다만, 메모리 주소는 실행 환경마다 달라지므로 하드코딩된 주소값을 비교하는 것은 금물입니다.
'Artificial Intelligence > 60. Python' 카테고리의 다른 글
| [PYTHON] is와 ==의 결정적 차이 2가지와 Interning 최적화 해결 방법 (0) | 2026.03.15 |
|---|---|
| [PYTHON] 모든 객체의 뿌리, PyObject 헤더 구조의 2가지 핵심 요소와 메모리 관리 방법 (0) | 2026.03.15 |
| [PYTHON] 객체 지향 설계를 바꾸는 Final과 ClassVar 활용 방법 2가지와 실무적 제약 해결 (0) | 2026.03.14 |
| [PYTHON] Multipledispatch를 이용한 함수 오버로딩 구현 방법 3가지와 정적 언어와의 차이 해결 (0) | 2026.03.14 |
| [PYTHON] 클래스 변수와 인스턴스 변수의 3가지 차이점과 가려짐(Shadowing) 문제 해결 방법 (0) | 2026.03.14 |