Python/기초

파이썬 변수, 변수는 어떻게 동작할까?

sdesign416 2026. 5. 21. 17:05

처음 Python을 배울때엔

변수는 단순히 '값을 저장하기 위한 이름' 정도로만 이해했다.

 

하지만 이번 수업을 통해

변수 안에 값이 직접 들어가는 것이 아니라,

메모리에 생성된 객체(Object)를 변수 이름이 참조(reference)하는 구조라는 것을 알게 되었다.

 

이 구조를 이해하고 나니,

조금 헷갈렸던 Python의 동작 방식이 훨씬 명확하게 느껴지기 시작했다.


변수란 무엇인가?

변수는 데이터를 저장하기 위해 사용하는 이름이며,

정확하게는 메모리에 저장된 객체를 가리키는 참조 이름이다.

a = "memory"

위 코드는 단순히 'memory' 라는 문자열을 변수에 넣는것이 아니라,

  • 'memory' 라는 문자열 객체가 힙 메모리(Heap Memory)에 생성되고
  • 변수 a 가 그 객체를 참조하게 된다.

즉, Python에서 변수는 값을 직접 저장하는 상자가 아닌

객체를 가리키는 이름(Name)에 가깝다.


Python의 변수 동작 방식

x = 10

위 코드가 실행되면 내부적으로는 다음과 같은 흐름이 발생한다.

  • 10 이라는 정수(int) 객체를 메모리(Heap)에 생성
  • 변수 x 가 해당 객체를 참조(reference)함
  • 객체 10의 타입은 정수형(int)이며, value는 10, ref count는 1이 된다.

즉, 객체는 type, value, ref count 등의 정보를 함께 가지고 있으며,
변수 x는 해당 객체의 메모리 주소를 참조하게 된다.

 

실제 동작 구조는 아래와 같다.

변수 이름 → 객체 참조 → 실제 데이터


네임스페이스(namespace)

Python에서 변수는 흩어져 존재하는 것이 아니라

내부적으로는 딕셔너리(dict) 형태의 네임스페이스에 저장되어 관리된다.

name = "김사과"
age = 20

print(globals())

globals()

globals() 함수는 현재 전역 범위에 정의된

변수, 함수, 클래스 등의 이름과 해당 객체 간의 매핑 정보를 딕셔너리 형태로 반환한다.

 

즉, Python 내부에서는 아래와 비슷하게 저장된다.

{
    "name": "김사과",
    "age": 20
}

이를 통해  Python의 변수는 단순한 저장 공간이 아닌

'이름과 객체를 연결하는 구조' 라는 것을 확인할 수 있다.


참조(Reference)와 Ref Count

Python 객체는 자신을 참조하는 변수의 개수를 기억하고 있다.

이것을 참조 카운트(ref count)라고 한다.

name = "김사과"

현재는 변수 name 하나만 "김사과" 객체를 참조하고 있으므로
ref count는 1이다.

another = name

name이 가진 "김사과"의 객체를 another 이라는 변수도 함께 참조하고 있으므로

이제 "김사과" 객체의 ref count는 2가 된다.

 

왜 이런 구조를 사용할까?

Python이 이러한 참조 구조를 사용하는 이유는
객체를 여러 변수가 함께 사용할 수 있도록 하고,
메모리를 보다 효율적으로 관리하기 위해서이다.

예를 들어 동일한 객체를 여러 변수가 참조할 경우,
새로운 객체를 계속 생성하지 않아도 되므로
불필요한 메모리 사용을 줄일 수 있다.


변수 재할당과 객체 변경

name = "김사과"
print(name)

name = "반하나"
print(name)

위의 경우 변수 name이 가리키던 "김사과"의 값을 수정하는 것이 아닌,

name이 새로운 객체를 다시 가리키게 되는 것 이다.

 

즉, 아래의 흐름으로 연결 대상이 바뀌는 것이다.

  • 처음에는 name"김사과"
  • 재할당 후 name   "반하나"

따라서 기존에 연결되어 있던 "김사과" 객체는

더 이상 name이 사용하지 않게 된다.

 

즉, Python에서 변수 재할당은
기존 객체를 수정하는 것이 아니라
변수가 참조하는 대상을 변경하는 과정에 가깝다.


객체 동일성 확인하기

Python에서는 같은 값을 가지는 객체가

같은 메모리 주소를 공유하는 경우도 있다.

is 연산자

is 는 값 비교가 아니라

'두 변수가 같은 객체를 참조하는가?' 를 확인하는 연산자이다.

id()

id() 함수는 객체의 고유 메모리 주소값을 반환한다.


변수 이름 사용 규칙

  1. 변수 이름은 알파벳(대·소문자 구별), 숫자, 밑줄로 구성될 수 있다
  2. 숫자로 시작할 수 없다.
  3. 공백을 포함할 수 없다.
  4. Python이 이미 사용하는 키워드는 사용할 수 없다.(if, class, for...)

변수 삭제하기

Python에서는 del 키워드를 사용하여

변수를 삭제할 수 있다.

isLover = False

print(isLover)

del isLover

위 처럼 isLover 변수를 삭제 후에는 해당 변수 이름으로 접근할 수 없다.

삭제 후 다시 호출 할 경우 아래 이미지와 같이 NameError가 발생한다.


del과 참조 카운트

name1 = "김사과"
name2 = name1		# 이 구문까지는 "김사과"의 ref count는 2

del name1		# name1 삭제 후 "김사과"의 ref count는 1

print(name2)		# name2는 아직 "김사과"를 참조중이므로 출력됨

위와 같이

처음에는 "김사과"의 ref count 가 2로 설정되어 있지만,

del 을 사용하여 name1을 삭제 후 ref count는 1로 변경된다.

하지만 name2는 아직 "김사과"를 참조 중이므로

"김사과"라는 객체는 메모리에서 삭제되지 않는다.


가비지 컬렉션(Garbage Collection)

Python에서 더 이상 사용하지 않는 객체는

자동으로 메모리에서 정리한다.

 

이를 가비지 컬렉션이라 한다.

 

객체의 참조 수 (ref count)가 0이 되면

Python은 해당 객체를 더 이상 사용하지 않는다고 판단하고
메모리 해제 대상으로 처리한다.


정리

처음에는 변수라는 개념을 단순히

'값을 저장하는 공간' 정도로만 이해하고 있었다.

 

하지만 Python에서는 변수 안에 값이 직접 저장되는 것이 아니라,
메모리에 생성된 객체를 참조하는 방식으로 동작한다.

 

특히 ref count, namespace, garbage collection 같은 개념들을 함께 배우면서
Python이 단순히 문법만 있는 언어가 아니라
메모리와 객체 중심으로 동작하는 구조를 가지고 있다는 점을 조금씩 이해할 수 있었다.