파이썬 변수란?
호텔로 배우는 변수 개념 (고등학교 정보)
값은 메모리 어딘가에 저장됩니다. 그런데 그 ‘어딘가’를 어떻게 다시 찾을까요? 오늘은 값에게 이름을 지어주는 방법, 변수를 배웁니다.
값은 어디로 갔을까?
지난 시간에 우리는 문자 'A'를 컴퓨터에 입력하면 인코딩을 거쳐 숫자 65(이진법 1000001)로 바뀐다는 걸 배웠어요. 그리고 그 65는 메모리 어딘가에 자리를 잡죠. 여기까지는 좋습니다. 그런데 한 가지가 궁금해집니다.
그럼 'A'가 바뀐 그 65는 메모리의 정확히 어디에 있을까요? 그리고 나중에 다시 쓰려면 어떻게 찾을까요?
이 질문에 답하려면 먼저 ‘메모리’가 어떻게 생겼는지 상상해 볼 필요가 있어요.
메모리는 거대한 호텔
메모리를 방이 수없이 많은 거대한 호텔이라고 상상해 봅시다. 이 호텔의 방 하나하나에는 서로 다른 고유한 번호가 붙어 있어요. 그 번호로 ‘어느 방인지’를 콕 짚어낼 수 있습니다.
컴퓨터가 값을 저장하면, 그 값은 이 호텔의 빈 방에 들어가 묵게 돼요. 가령 값 10을 저장하면, 10은 방을 하나 배정받아 자리를 잡습니다. 그 방 번호만 알면, 10이 어디 묵는지 바로 찾을 수 있어요.
사실 진짜 메모리도 이렇게 생겼어요. 값이 들어가는 셀(방)이 일렬로 죽 이어져 있고, 셀마다 고유한 주소가 달려 있죠. 호텔에서 방 번호가 하던 일을, 메모리에서는 주소가 하는 거예요. 고층 호텔 옆에 나란히 놓아 보면 — 구조가 정말 똑 닮았습니다.
왼쪽 메모리의 셀 하나가, 오른쪽 호텔의 방 하나. 방 안 숫자는 값을 이진법으로 적은 것이고, 괄호 안이 우리가 읽는 실제 값이에요.
실습 ① — 주소 확인하기
정말로 값마다 자기 주소가 있을까요? 파이썬에는 값이 저장된 메모리 주소를 알려주는 id() 함수가 있어요. 직접 확인해 봅시다.
print(id(10)) print(id(100)) print(id("안녕"))
140712834563824
140712901447920
이 긴 숫자가 바로 메모리 주소예요. 호텔로 치면, 값이 묵는 방의 번호인 셈이죠. 주소는 실행할 때마다, 컴퓨터마다 달라질 수 있어요 — 호텔에 갈 때마다 다른 방을 배정받는 것처럼요.
주소는 외우기 어렵다
그런데 잠깐. 방금 본 140712834561234 — 이 주소를 외울 수 있는 사람 있나요? 방 번호가 열다섯 자리나 되는 호텔인 셈이죠. 너무 길고 복잡합니다.
호텔 프런트를 떠올려 봐요. 손님을 찾을 때 ‘140712834561234호 손님’이라고 하지 않죠. 그냥 “김민준 님” 하고 이름을 부릅니다. 이름만 대면, 몇 호에 묵는지는 프런트가 알아서 찾아 주니까요.
컴퓨터도 똑같이 합니다. 긴 주소를 매번 외우는 대신, 값에 이름을 붙여 두고 그 이름으로 부르는 거예요. 이 이름이 바로 변수(variable). 그리고 이름만 듣고 방을 찾아 주는 프런트 역할은 — 파이썬이 맡습니다.
외우기 어려운 주소 대신, 기억하기 쉬운 이름으로 부른다 — 그 이름이 변수, 이름으로 방을 찾아 주는 프런트가 파이썬.
변수 선언하기
값에 이름을 붙이는 것을 변수 선언이라고 합니다. 방법은 아주 간단해요.
예를 들어 이름을 age로, 값을 10으로 정하면 이렇게 됩니다.
age = 10
이 한 줄의 의미를 풀어 보면 이렇습니다.
10이라는 값을 메모리 어딘가에 저장하고,- 그 값이 묵는 방에
age라는 이름표를 붙여라.
책상이나 사물함에 자기 이름표를 붙여 ‘내 자리’로 만드는 것과 똑같아요. 값이 묵는 방에 이름표를 붙여 두면, 그때부터 그 이름으로 값을 부를 수 있어요.
여기서 = 기호는 수학의 ‘같다’가 아니에요! “오른쪽 값을 왼쪽 이름에 넣어라”라는 뜻이에요. 그래서 이 기호를 대입 연산자라고 부릅니다.
말로 풀면 — “10이 묵는 방에 age라는 이름표를 달아줘.”
이름표에도 규칙이 있다
이름표라고 해서 아무 이름이나 달 수 있는 건 아니에요. 파이썬이 이름을 알아들으려면 몇 가지 규칙을 지켜야 합니다.
- 영문자, 숫자, 밑줄(
_), 그리고 한글을 쓸 수도 있어요. - 숫자로 시작할 수 없어요.
- 대문자와 소문자를 구분해요. (
age와Age는 서로 다른 변수!) - 공백(띄어쓰기)은 쓸 수 없어요.
- 파이썬이 미리 정해둔 예약어는 쓸 수 없어요. (
if,for,class등) - (권장) 한글도 되지만(예:
나이 = 10), 변수 이름은 전 세계 공통어인 영문으로 쓰는 걸 권해요(예:age = 10). - (권장) 값의 의미가 드러나는 이름이 좋아요.
| ❌ 잘못된 이름 | 이유 | ⭕ 올바른 이름 |
|---|---|---|
2age | 숫자로 시작 | age2 |
my age | 공백 포함 | my_age |
class | 예약어 | class_no |
a | 의미가 없음 | student_count |
규칙만 지키면 a, b도 동작은 해요. 하지만 나중에 코드를 다시 봤을 때 무슨 값인지 바로 알 수 있는 이름이 훨씬 좋은 이름표랍니다.
실습 ② — 이름표를 달고 확인하기
이제 직접 확인해 봐요. 주소는 변수 이름에 붙어 있을까요, 아니면 그 변수가 가리키는 값에 붙어 있을까요?
a = 10 b = a # a가 가리키는 그 방을 b도 가리킨다 c = 20 # c는 다른 값 print(id(a)) # a가 가리키는 메모리 주소 print(id(b)) # → a와 똑같아요! (b = a 니까) print(id(c)) # → 다른 방이에요 (값이 다르니까)
140712834561234 ← a와 같은 방! (b = a)
140712834569999 ← 다른 값 = 다른 방
b는 a와 이름은 다르지만 같은 방이에요 — b = a로 a가 가리키는 값을 함께 가리키니까요. 반대로 c는 값이 달라서 다른 방에 묵죠. 즉 주소는 변수 이름이 아니라, 그 변수가 가리키는 값에 붙어 있답니다. (그러니 값이 바뀌면 주소도 바뀌겠죠? 바로 다음 장 이야기예요.)
직접 해보기 메모리 호텔 시뮬레이터
변수 이름과 값을 넣고 ‘선언 / 값 바꾸기’를 눌러 보세요. 같은 이름에 다른 값을 넣으면 — 새 값은 다른 방에 자리 잡고 이름표만 옮겨 가요. 주소(…○○○○)가 어떻게 달라지는지 확인해 보세요!
변수는 변할 수 있다 — 이름표를 옮겨요
변수의 진짜 힘은 값이 바뀔 수 있다는 거예요. 그래서 ‘변할 변(變)’, 변수라고 부르죠. 값을 바꾸면 무슨 일이 일어나는지, 메모리 호텔에서 짧은 상황극으로 봅시다.
point = 3000 print(point) # 3000 point = 8000 # 8000은 다른(새) 방에 만들어지고, point 이름표만 옮겨 감 print(point) # 8000
이름표가 정말 다른 방을 가리키게 됐는지 id()로 확인해 볼까요?
point = 3000 print(id(point)) # 140712834561234 point = 8000 print(id(point)) # 140712834567890 ← 주소가 달라졌어요!
주소가 달라졌죠? 상황극 그대로예요. 값 8000은 3000이 묵던 방이 아니라 다른 빈 방(다른 주소)에 새로 만들어졌고, 이름표 point가 그 방으로 옮겨 붙어 이제 8000을 가리킵니다. 그래서 id(point)가 달라진 거예요. 기억할 건 하나 — point는 이제 8000을 가리킨다.
새 값이 만들어지는 순간, 이전 값은 아직 그 방에 머물고 있어요. 그러니 새 값은 그 방을 쓸 수 없고, 비어 있는 다른 방에 자리를 잡죠. 그리고 어떤 이름표도 그 값을 가리키지 않게 되면, 파이썬이 이전 값을 조용히 체크아웃시켜 방을 비웁니다. 이걸 가비지 컬렉션(garbage collection)이라고 해요 — 아무도 찾지 않는 손님을 체크아웃시키는 셈이죠.
👆 위 시뮬레이터에서 한 변수에 값을 두 번 넣어 보세요. 새 값은 다른 방에 자리 잡고 이름표만 옮겨 가며, 이전 값은 (아직 체크아웃 전이라) 잠시 그 자리에 남습니다.
변수를 쓴다는 것 = 이름으로 손님 부르기
변수를 쓴다는 건, 프런트에 “price 님 좀 불러 주세요” 하고 부탁하는 것과 같아요. 이름을 대면 파이썬이 그 이름표가 붙은 방을 찾아가, 거기 묵는 값을 데려와 그 자리에 써 줍니다.
price = 1500 count = 3 # 프런트가 price 님(1500)과 count 님(3)을 불러와 곱한다 total = price * count print(total) # 4500
price * count를 쓰면, 파이썬은 프런트처럼 두 이름표가 붙은 방을 찾아가 값 1500과 3을 불러와 곱합니다. 그 결과 4500에 total이라는 새 이름표를 달아 주고요. 이렇게 변수는 계산의 재료가 돼요. 프로그래밍에서 변수가 빠질 수 없는 이유죠.
조금 더 알아보기
① 이름표를 달기 전에는 부를 수 없어요. 선언하지 않은 변수를 쓰면, 파이썬은 ‘그런 이름의 방은 없는데?’ 하고 오류를 냅니다.
print(height) # 아직 선언한 적 없는 변수
→ 값을 쓰기 전에는 반드시 먼저 선언해야 한다는 뜻이에요.
② 변수에는 여러 종류의 값을 담을 수 있어요. 숫자뿐 아니라 문자(문자열), 소수, 참/거짓까지요. 파이썬은 값의 종류를 미리 정하지 않아도 알아서 처리해 줘요.
name = "지수" # 문자열 score = 95.5 # 소수 passed = True # 참/거짓
이렇게 값마다 종류가 있는데, 이 종류를 자료형이라고 해요. 자료형은 다음 시간의 주인공이랍니다 — 그때 하나하나 자세히 만나봐요!
호텔 비유 한눈에 정리
오늘 배운 내용을, 처음의 호텔 이야기로 정리해 볼게요.
| 호텔 이야기 | 파이썬 | |
|---|---|---|
| 거대한 호텔 | ↔ | 메모리(memory) |
| 방 번호 | ↔ | 메모리 주소 · id() |
| 방에 묵는 손님 | ↔ | 값(value) |
| 방에 붙인 이름표 | ↔ | 변수(variable) |
| 이름표 달기 | ↔ | 변수 선언 (age = 10) |
| 이름표 옮겨 달기 | ↔ | 값 재대입 (age = 20) |
| 아무도 찾지 않는 손님 체크아웃 | ↔ | 가비지 컬렉션 |
| “○○ 님 불러 주세요” | ↔ | 변수 사용 (price * count) |
확인 퀴즈 오늘 배운 것, 점검!
네 문제를 풀어 보세요. 정답을 고르면 바로 해설이 나와요.
Q1. 다음 중 파이썬에서 올바른 변수 이름은?
정답: _score — 밑줄(_)로 시작할 수 있어요. 2age는 숫자로 시작해서, my age는 공백이 있어서, if는 예약어라서 안 됩니다.
Q2. age = 10 에서 = 기호의 의미로 알맞은 것은?
정답: 오른쪽 값을 왼쪽 변수에 넣는다 — =는 ‘같다’가 아니라 대입 연산자예요. 이름표를 달아주는 기호랍니다.
Q3. 다음 코드의 출력 결과는?
x = 5 → x = 8 → print(x)
정답: 8 — x 이름표를 5에서 8로 옮겨 달았으니, 지금 x가 가리키는 값은 8이에요.
Q4. 값이 저장된 메모리 주소를 알려주는 함수는?
정답: id() — id()는 값이 저장된 메모리 주소(호텔로 치면 방 번호)를 돌려줘요.
한 걸음 더 — 생각해볼 문제
본문 이야기(그리고 위 시뮬레이터)대로라면, 같은 값이라도 새로 만들면 다른 방(다른 주소)에 들어가야 해요. 실제로 큰 수는 그렇습니다. 그런데 아주 작은 수로 직접 실험하면, 뜻밖의 결과가 나와요.
# 파이썬 셸(>>>)에 한 줄씩 입력해, 주소를 직접 찍어 비교해요 # 작은 수 >>> c = 10 >>> d = 10 >>> id(c) 140712834561200 >>> id(d) 140712834561200 # c와 똑같은 주소?! # 큰 수 >>> e = 1000 >>> f = 1000 >>> id(e) 140712999887744 >>> id(f) 140712999887320 # e와 다른 주소 — 다른 방!
큰 수 1000은 두 번 만들면 서로 다른 방에 묵는데, 작은 수 10은 왜 같은 방을 쓸까요? 잠시 예상해 본 뒤, 아래 설명을 펼쳐 보세요.
🔑 자세한 설명 보기
파이썬은 자주 쓰는 작은 정수를 미리 만들어 둡니다. CPython 기준으로 대략 -5부터 256까지의 정수는, 프로그램이 시작될 때 딱 하나씩 만들어 두고 계속 재사용해요. 이 미리 만들어 둔 값들이 바로 단골 손님이에요.
c = 10,d = 10은 둘 다 ‘미리 만들어 둔 그 10’이라는 같은 단골 손님을 가리켜요. 그래서id가 같습니다.- 이 단골 손님들은 이름표가 하나도 없어도 체크아웃하지 않아요. 파이썬이 계속 모시고 있으니까요. 그래서 본문의 ‘아무도 안 찾으면 체크아웃된다(가비지 컬렉션)’ 규칙에서도 예외랍니다.
- 반대로
1000처럼 큰 수는 쓸 때마다 새로 만들어져서, 같은 값이라도 서로 다른 방(다른 주소)을 가질 수 있어요.
그러니까 본문의 ‘옮기기’ 이야기는 이렇게 새로 만들어지는 일반적인 값에 딱 들어맞고, 작은 수는 특별한 단골 손님 상황이에요. 자주 쓰는 작은 수를 매번 새로 만들지 않으려는 파이썬의 작은 최적화인 셈이죠.
① 왜 하필 범위가 -5 ~ 256일까요? ② 문자열에도 비슷한 재사용(‘인터닝’)이 있을까요? ③ 위 코드를 셸이 아니라 하나의 .py 파일에 몰아 쓰면 큰 수도 같은 주소가 나올 수 있어요 — 파이썬이 같은 상수를 하나로 합치기도 하거든요. 왜 그런지 id()로 직접 실험해 보세요! (정확한 동작은 파이썬 구현·버전에 따라 다를 수 있어요.)
댓글
댓글 쓰기