콘텐츠 내 자동삽입광고

광고1

posted by 초코생크림빵 2025. 8. 5. 20:20
반응형

질문)

변수는 메모리 주소를 가리키는 이름일 뿐이며, 실제 값은 메모리의 다른 곳에 객체로 저장됩니다. 여기에서 메모리 주소를 가리킨다는건 변수에는 값이 들어 있는 주소값이 할당되는것이고, 실제값은 해당 메모리주소에 값이 들어있다는 뜻인가요?

 

네, 정확하게 이해하셨습니다. 말씀하신 내용이 바로 파이썬이 변수를 다루는 핵심 원리입니다.

좀 더 자세히 설명해 드릴게요.

1. 변수는 '이름표'입니다.

파이썬에서 변수는 값을 담는 상자가 아닙니다. 대신, 메모리에 저장된 객체(값)를 가리키는 이름표 역할을 합니다.

예를 들어, a = 10 이라는 코드를 실행하면:

  1. 메모리의 어딘가에 정수 10이라는 객체가 생성됩니다.
  2. 이 객체가 저장된 메모리 주소가 있습니다.
  3. 변수 a는 그 메모리 주소를 참조(reference)합니다.

따라서 a를 출력하면, 파이썬은 a가 가리키는 메모리 주소로 찾아가 그곳에 있는 실제 값(10)을 가져와 보여주는 것입니다.

2. 변수가 다른 값을 가리키게 될 때

만약 a = "Hello"라는 코드를 이어서 실행하면 어떻게 될까요?

  • 새로운 문자열 "Hello" 객체가 메모리의 다른 주소에 생성됩니다.
  • 변수 a는 이제 이 새로운 객체의 주소를 가리키게 됩니다.

이전 값인 정수 10 객체는 더 이상 a에 의해 참조되지 않습니다. 파이썬의 가비지 컬렉터(Garbage Collector)가 이 객체를 정리하여 메모리를 회수합니다.

3. 변수와 메모리 주소 확인하기

id() 함수를 사용하면 객체의 메모리 주소(고유 ID)를 직접 확인할 수 있습니다.

 

Python

a = 10
print(f"변수 'a'가 가리키는 객체의 주소: {id(a)}")

a = 20
print(f"변수 'a'가 새로운 객체(20)를 가리키는 주소: {id(a)}")

b = 10
print(f"변수 'b'가 가리키는 객체의 주소: {id(b)}")

 

 

실행 결과:

변수 'a'가 가리키는 객체의 주소: 140732890533608
변수 'a'가 새로운 객체(20)를 가리키는 주소: 140732890533928
변수 'b'가 가리키는 객체의 주소: 140732890533608

 

위 결과에서 볼 수 있듯이, a에 다른 값(20)을 할당하면 메모리 주소가 바뀝니다.

또한, a와 b에 동일한 값(10)을 할당했을 때 메모리 주소가 같습니다. 이는 파이썬이 메모리 효율성을 위해

작은 정수와 같은 불변 객체들은 미리 생성해두고 재사용하기 때문입니다. 이를 객체 풀링(Object Pooling)이라고 합니다.

이러한 참조 방식 덕분에 파이썬은 변수의 타입을 유연하게 바꿀 수 있고, 메모리 관리를 자동으로 처리할 수 있는 것입니다.

 

★ ★ ★ ★ 작은 정수의 의미에 대해 정리  ★ ★ ★ ★

여기서 '작은 정수'는 파이썬 인터프리터가 성능 최적화를 위해 미리 메모리에 생성해 두고 재사용하는 특정 범위의 정수를 의미합니다.

정확한 범위는 CPython(가장 일반적으로 사용되는 파이썬 인터프리터) 기준으로는 -5부터 256까지입니다. 이 범위는 파이썬 개발자들이 경험적으로 가장 자주 사용된다고 판단한 수치입니다.

왜 이런 최적화가 필요할까요?

파이썬은 모든 것을 객체로 다루기 때문에, 1이라는 작은 숫자 하나를 생성할 때도 객체를 만들고 메모리를 할당하는 오버헤드가 발생합니다. 만약 프로그램에서 1이라는 숫자를 수백 번, 수천 번 사용한다면 매번 새로운 객체를 만드는 것은 매우 비효율적입니다.

이러한 비효율성을 막기 위해 파이썬은 프로그램이 시작될 때 미리 -5부터 256까지의 정수 객체를 생성하여 '정수 캐시(Integer Cache)' 또는 **'정수 풀(Integer Pool)'**에 저장해둡니다.

작동 방식

  1. 변수 할당: a = 10 이라는 코드를 실행하면, 파이썬은 먼저 정수 10이 정수 캐시 범위(-5 ~ 256)에 포함되는지 확인합니다.
  2. 객체 재사용: 10은 이 범위에 포함되므로, 새로운 객체를 만들지 않고 이미 메모리에 있는 기존의 정수 10 객체를 변수 a가 가리키도록 합니다.
  3. 새로운 객체 생성: 만약 b = 300 이라는 코드를 실행하면, 300은 캐시 범위 밖이므로 새로운 정수 객체 300이 메모리에 생성되고, b가 이 객체를 가리키게 됩니다.

이러한 최적화 덕분에, 프로그램에서 자주 사용되는 작은 정수들은 메모리 주소가 항상 동일합니다.

예시 코드로 확인하기

id() 함수를 사용하면 이 원리를 명확하게 알 수 있습니다.

Python

# 작은 정수 (캐시 범위 안)
a = 100
b = 100
print(f"a와 b는 같은 객체를 가리키는가? {a is b}")
print(f"a의 메모리 주소: {id(a)}")
print(f"b의 메모리 주소: {id(b)}")
# 결과: True, 메모리 주소가 동일함

# 큰 정수 (캐시 범위 밖)
c = 300
d = 300
print(f"c와 d는 같은 객체를 가리키는가? {c is d}")
print(f"c의 메모리 주소: {id(c)}")
print(f"d의 메모리 주소: {id(d)}")
# 결과: False, 메모리 주소가 다름

 

이처럼 '작은 정수'는 파이썬의 내부적인 성능 최적화 기법을 의미하며, 개발자가 직접 이 부분을 제어할 필요는 없지만 파이썬이 어떻게 동작하는지 이해하는 데 큰 도움이 됩니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형

콘텐츠 내 자동삽입광고