끝나지 않는 프로그래밍 일기

1. 변수(Variable)

다른 언어들과 마찬가지로 파이썬에서도 변수(Variable)라는 개념이 당연히 존재하며, 이 변수라는 것은 임시로 혹은 영구적으로 값을 기억해두기 위한 저장소를 말합니다. 이러한 변수는 왜 필요한 것일까요? 이해를 돕기 위해 예를 하나 들어보도록 하겠습니다. 우리가 마을 근처의 마트에서 과자를 사려고 하여 천원 짜리 지폐를 들고 집 밖을 나섰다고 가정합니다. 근처 마트를 방문하고 나서 고른 과자의 가격이 600원이라고 하였을 때, 우리가 가지고 있는 돈인 1000원에서 600원을 뺀 나머지인 400원을 거스름돈으로 받게 됩니다. 이를 컴퓨터 상에서 표현한다고 한다면, 아래와 같을 것입니다.

money = 1000
cookiePrice = 600
money = money - cookiePrice
print(money)

결과:

400


위 코드에서 money와 cookiePrice가 변수이며, 변수가 담고 있는 값은 항상 고정되어 있는게 아니라 변할수 있습니다. 1행을 보시면 1000이란 값이 변수 money에 들어가고, 2행에서는 600이란 값이 변수 cookiePrice에 들어갑니다. 그리고 변수 money와 cookiePrice가 담고 있는 값을 가지고 연산을 한 뒤, 그 결과를 다시 money에 저장합니다. 그리고 최종적으로 money의 값을 출력합니다.


쉽게 말하면 변수는 '값을 담아두는 상자'라고 할 수 있지만, 실제로는 값을 담아두는게 아니라 어떠한 값에 이름표를 붙이는 것과 같습니다. 변수를 직접 정의하면서 주의하실 부분은, 왼쪽에 변수명이 와야 한다는 것입니다. 예를 들어, 아래와 같은 경우를 보도록 하겠습니다.

>>> money = 1000
>>> 1000 = money
SyntaxError: can't assign to literal

첫 줄에서 작성된 코드는 아무런 에러 없이 정상적으로 money란 변수가 1000을 담고 있습니다. 그런데, 두번째 줄에서 작성된 코드는 '리터럴(문자)에 할당할 수 없습니다.'와 같은 에러가 발생하게 됩니다. 기본적으로 =(치환 연산자)는 오른쪽에 있는 식의 결과값을 그대로 왼쪽으로 가져다 놓는 것이기 때문에 이러한 에러가 발생하는 것입니다. 즉, '상수인 1000에 변수인 money를 가져다 놓으라고?'와 같이 해석이 되는 것입니다. (사소한 부분이지만, 혹시나 이 부분에 대해서 궁금해 하실 분들을 위해 추가적으로 내용을 덧붙여 놓았습니다.)  


아래의 '2. 파이썬에선 모든게 객체다!'에서 변수는 정확히 어떠한 것이고, 어떤 값을 담고 있는지 설명하고 있습니다. 잘 이해가 되지 않으시는 분들은 2번을 생략하시고 3번부터 보셔도 좋습니다. 만약 2번을 이해할 수 없어도 크게 무리는 가지 않으니 걱정하지 마시길 바랍니다. 객체에 대해서 이해가 어느정도 되었을때, 3편으로 다시 돌아와서 보셔도 되며 이는 혹여나 추후에 객체에 관해서 더 심화적인 부분에 대한 궁금증이 생기게 될 수 있으므로 추가적으로 마련한 부분입니다.


2. 파이썬에선 모든게 객체(Object)다!

파이썬에선 모든게 객체(Object)라니, 객체란 것은 도대체 무엇을 말하는 것일까요? 우리가 앞으로 배우게 될 함수, 모듈, 리스트, 튜플 등 모든 것을 객체라고 할 수 있습니다. 첫 예제에서의 1000과 600도 결코 예외가 아닙니다. 어떤 것이든, 객체라고 할 수 있습니다. 위에있는 예제 코드를 다시한번 보도록 합시다.

money = 1000
cookiePrice = 600
money = money - cookiePrice
print(money)

우선은 1행의 코드부터 보시게 되면, 변수 money와 1000이라는 값을 지닌 객체가 만들어집니다. 사실은, 1000이란 값이 그대로 money에 대입이 되어 money가 1000이란 값을 지니는게 아니라 1000이라는 값을 지니는 객체를 새로 만들어내고 그 객체가 저장되어 있는 공간에다 money라는 이름표를 붙이는 것이라고 생각할 수 있습니다. 즉, 변수 money는 직접적으로 1000이란 값을 가지고 있는게 아니라, 1000이라는 값이 저장되어 있는 공간의 주소를 담고 있는 것이라고 할 수 있습니다. 2행도 마찬가지로, cookiePrice라는 변수가 600이라는 값을 지닌 객체가 저장된 공간을 가리키는 것이라고 할 수 있습니다. 이해를 위해 한가지 예를 더 들어보도록 하겠습니다.

위 그림에서 코드 영역에 있는 코드가, 메모리 영역에서는 변수 X, Y, Z가 만들어지고, 객체 3과 5가 만들어지게 됩니다. 여기서 X, Y는 동일하게 3이라는 값을 가진 객체를 가리키게 되고, Z는 5라는 값을 가진 객체를 가리키게 되는 것입니다. 만약 Y에 4를 넣으려고 한다면, 더이상 객체 3을 가리키는게 아니라 새로운 객체 4를 가리키게 됩니다. 파이썬 내에는 id라는 내장 함수가 존재하고, 이 id 함수는 객체의 주소를 돌려주는데 여기서 잠시 id 함수를 통해 정말 같은 곳을 가리키고 있는지 확인을 해보도록 하겠습니다. (함수에 대해 이해가 안가시면, 함수에 대한 강좌를 미리 보고 오시는 것도 괜찮습니다.)

X = 3
Y = 3
Z = 5
print(id(X), id(Y), id(3), id(Z), id(5))

결과:

507098848 507098848 507098848 507098912 507098912


결과를 보시면 변수 X와 Y은 객체 3을 가리키고, 변수 Z는 객체 5를 가리킨다고 말할 수 있습니다. 즉, 객체 3의 주소값과 변수의 주소값이 모두 일치하는 것입니다. 이번엔 값을 조금 바꾸어 예제의 결과를 확인하도록 합시다.

X = 300
Y = 50
Z = 257
print(id(X), id(Y), id(Z), id(300), id(50), id(257))

결과:

42178032 507100352 42179216 52031024 507100352 52031088


위 결과를 보시면, 변수 Y와 객체 50의 주소값은 동일하지만 변수 X, Z와 300, 257은 서로 다른 것을 보실 수 있습니다. 아래의 문장은 일반적인 정수 객체에 대한 설명의 일부를 파이썬 레퍼런스 사이트에서 가져온 것입니다. 해당 부분을 레퍼런스 사이트에서 보시려면 이곳을 클릭하시면 됩니다.

The current implementation keeps an array of integer objects for all integers between -5 and 256
when you create an int in that range you actually just get back a reference to the existing object. 

'현재 구현에서는 -5~256 사이의 모든 정수에 대해서 객체 배열을 가지고 있기 때문에 그 사이의 정수를 정의하면 기존에 있는 객체를 참조합니다.'라고 나와있으며, 이는 -5~256 사이의 정수를 X, Y, Z에 넣을때는 미리 만들어져 있는 객체를 참조하지만 범위를 넘어선 경우에는 객체를 새로 정의한다고 합니다. 


아직 이부분이 이해가 되지 않으신다고 해도 괜찮습니다. 어느정도 배우시다가 다시 이부분을 보셔도 괜찮고, 예제 코드를 보는것 보다는 경험이 중요하니 계속 위 코드를 응용하여 결과를 확인하며 경험을 쌓는게 중요합니다.


3. 변수의 이름 작성 규칙

이런 변수란 것을 만들려면 어떻게 해야 할까요? 우리는 이미 위 예제 코드에서 두개의 변수를 만들었으며, 인터프리터식 언어답게 변수를 알아서 인식하며 '=' 기호를 통해서 변수를 만들 수 있습니다. 변수명에는 문자, 숫자, 언더바(_)를 포함할 수 있으며 숫자는 가장 처음에 등장할 수 없습니다. 또한 파이썬에선 대소문자를 구분하기 때문에 apple이란 변수와 Apple이란 변수는 서로 다릅니다.

4pple = 10 # 숫자가 가장 처음에 등장했다. 이 경우에는 구문 에러가 발생한다.
admin = 50 # 정상적으로 admin이란 변수가 만들어진다.
Apple = 60 # 정상적으로 Apple이란 변수가 만들어진다.
apple = 70 # 대소문자를 구분하기 때문에 앞에 나온 변수인 Apple과는 별개의 변수이다.
print(admin, Apple, apple) # 세 변수의 값을 모두 출력한다. 출력된 결과는 50 60 70이다.

또한, 아래에 있는 키워드는 변수명으로 사용할 수 없습니다.

False, None, True, and, as, assert, break, class, continue, def, del, elif, else, except, finally, for, from, global, if, import, in, is, lambda, nonlocal, not, or, pass, raise, return, try, while, with, yield


위에 있는 키워드들은 파이썬 문법에서 사용되는 단어로, 특별한 의미를 지니고 있습니다. 아래와 같이 변수를 만들 수는 없다는 말입니다. (주의하실 점은 위의 키워드들은 대소문자가 구분이 된다고 합니다.)

None = 3
yield = 15
global = 663

위의 코드를 IDLE에 입력하시면 "Invalid syntax(잘못된 구문입니다.)", "can't assign to keyword(키워드에 할당할 수 없습니다.)"와 같은 에러를 만날 것입니다. 이처럼, 키워드는 변수의 이름으로 쓰일 수 없다는 사실을 기억해두시고 계시기 바랍니다. 이건 추가적인 내용인데, 변수명에는 한글도 사용할 수 있습니다. 아래 예제를 한번 보도록 합시다.

>>> 사과 = 10
>>> 포도 = 5
>>> print(사과, 포도)
10 5

위 예제를 보시면 한글이 들어간 변수명도 사용할 수 있음을 확인할 수 있습니다. 지금까지 배운 내용을 되돌아 보면서 변수를 선언하고, 선언한 변수를 통해 이것저것 예제를 한번 만들어보면서 경험을 쌓아보시길 바랍니다. 강좌 내용을 계속 보는것보다 자기가 한번 경험하고 나서 깨닫는게 가장 좋은 방법입니다.


Q1. 실생활 적용 문제 (☆☆☆☆)

민수는 인근 마켓에 들려서 과자 두 봉지와 아이스크림 한 개를 골라들고 가격에 맞는 돈을 지불하려 지갑을 열었습니다. 여기서 민수는 상대방에게 얼마를 건네주어야 할까요? (과자 한 봉지당 가격은 1200원이며, 아이스크림 한 개당 가격은 1500원이라고 가정합니다. 여기서 변수 세 개(과자 가격, 아이스크림 가격, 최종적으로 지불해야할 금액이 담긴 변수)를 이용하여 최종적으로 얼마를 지불해야 하는지 그 금액을 출력하세요.


Q2. 변수의 이름 작성 규칙 문제 (☆☆☆☆)

아래에서 사용할 수 없는 변수명을 모두 고르고 그 이유를 설명하세요.


class  normal 1st _python 변수 except