기초

hello world를 출력하는 것만으로는 부족할 겁니다, 그렇죠? 그 이상의 무언가를 하고 싶으실 텐데, 아마 뭔가를 입력받아 그것을 조작해서 어떤 결과를 구하고 싶을 겁니다. 파이썬에서는 상수와 변수를 이용해 그렇게 할 수 있으며, 그 밖의 다른 개념에 대해서도 이번 장에서 배워보겠습니다.

주석

주석(comment)# 기호 바로 오른쪽에 오는 텍스트를 말하며, 주로 코드를 읽는 분들을 위한 메모의 역할을 합니다.

다음 예제나

print('hello world') # print는 함수입니다

다음 예제를 봅시다.

# print는 함수입니다
print('hello world')

다음과 같은 목적으로 프로그램에 유용한 주석을 가능한 한 많이 만드세요.

  • 전제조건을 설명
  • 중요 의사결정을 설명
  • 중요 세부사항을 설명
  • 해결하고자 하는 문제를 설명
  • 프로그램에서 극복해야 할 문제들을 설명
  • 기타 등등

코드는 '어떻게'를 말해주고, 주석은 여러분이 '왜' 그렇게 하는지를 설명해야 합니다.

주석은 프로그램이 어떻게 동작하는지 쉽게 이해할 수 있게 해줘서 프로그램 코드를 읽는 사람에게 유용합니다. 6개월 후에 그 사람이 바로 여러분이 될 수도 있습니다!

리터럴 상수

리터럴 상수(literal constant)의 한 가지 예는 5, 1.23 같은 숫자나 'This is a string'이나 "It's a string!" 같은 문자열입니다.

이를 리터럴이라고 부르는 이유는 글자 그대로(literal) 값 자체를 그대로 사용하기 때문입니다. 2라는 숫자는 언제나 다른 뭔가가 아닌 그 자체를 나타내며, 값을 변경할 수 없기 때문에 상수(constant)에 해당합니다. 입니다. 따라서 이 모든 것들을 리터럴 상수라고 합니다.

숫자

숫자에는 크게 정수(integer)와 실수(float)라는 두 가지 타입(type)이 있습니다.

정수의 예로 소수점이 없는 2가 있습니다.

부동 소수점 수(floating point number, 또는 짧게 줄여서 float)의 예로 3.2352.3E-4가 있습니다. E 표기법은 10의 제곱을 나타냅니다. 이 경우 52.3E-452.3 * 10^-4^를 의미합니다.

숙련된 프로그래머를 위한 메모

파이썬에는 long 타입이 따로 없습니다. int 타입으로 임의 크기의 정수를 만들 수 있습니다.

문자열

문자열(string)은 글자의 나열(sequence of character)입니다. 기본적으로 문자열은 단어의 묶음에 불과합니다.

앞으로 작성할 거의 모든 파이썬 프로그램에서 문자열을 사용하게 될 테니 이어지는 내용을 신경 써서 살펴봅시다.

작은따옴표

'Quote me on this'처럼 작은따옴표를 이용해 문자열을 나타낼 수 있습니다.

작은따옴표 안의 모든 공백 문자(예: 공백과 탭)는 그대로 유지됩니다.

큰따옴표

큰따옴표로 묶은 문자열은 작은따옴표로 묶은 문자열과 정확히 동일한 방식으로 동작합니다(예: "What's your name?").

삼중따옴표

삼중따옴표(""" 또는 ''')를 이용해 여러 줄에 걸친 문자열을 나타낼 수 있습니다. 삼중따옴표 내에서는 작은따옴표와 큰따옴표를 자유롭게 쓸 수 있습니다. 다음 예제를 봅시다.

'''This is a multi-line string. This is the first line.
This is the second line.
"What's your name?," I asked.
He said "Bond, James Bond."
'''

문자열은 불변적이다

이게 무슨 뜻이냐면 파이썬에서 문자열을 한번 만들고 나면 이를 변경할 수 없다는 의미입니다. 별로 좋지 않아 보일 수도 있겠지만 실제로는 그렇지 않습니다. 나중에 살펴볼 다양한 프로그램에서 이것이 왜 제약사항이 아닌지 보겠습니다.

C/C++ 프로그래머를 위한 메모

파이썬에는 char 데이터 타입이 따로 없습니다. 이 타입이 필요한 이유가 그다지 없으며 여러분한테도 필요하지 않을 것입니다.

펄/PHP 프로그래머를 위한 메모

작은따옴표로 감싼 문자열과 큰따옴표로 감싼 문자열은 동일하고 아무런 차이점이 없다는 점을 기억하세요.

format 메서드

간혹 여러 정보를 조합해서 문자열을 만들고 싶을 때가 있습니다. 이때 format() 메서드가 유용합니다.

다음 코드를 str_format.py라는 이름의 파일로 저장합니다.

age = 20
name = 'Swaroop'

print('{0} was {1} years old when he wrote this book'.format(name, age))
print('Why is {0} playing with that python?'.format(name))

출력 결과는 다음과 같습니다.

$ python str_format.py
Swaroop was 20 years old when he wrote this book
Why is Swaroop playing with that python?

동작 원리

문자열로 어떤 서식 명세(specification)를 만들고 format 메서드를 호출해 그러한 서식 명세를 format 메서드에 전달한 각 인수로 대체할 수 있습니다.

첫 번째 예제에서 {0}format 메서드에 전달한 첫 번째 인수인 name 변수에 대응됩니다. 이와 마찬가지로 두 번째 서식 명세는 {1}이고 format 메서드에 전달한 두 번째 인수인 age에 대응됩니다. 파이썬은 0부터 숫자를 세기 시작하므로 첫 번째 위치는 0번 인덱스이고, 두 번째 위치는 1번 인덱스가 된다는 점에 유의합니다.

위 예제는 다음과 같은 문자열 연결(concatenation)을 이용해도 똑같이 처리할 수 있다는 점을 알아둡니다.

name + ' is ' + str(age) + ' years old'

하지만 이렇게 하면 코드가 지저분하고 오류가 발생하기 쉽습니다. 다음으로 위 예제에서는 숫자를 문자열로 명시적으로 변환했지만 format 메서드에서는 자동으로 문자열로 변환됩니다. 마지막으로 format 메서드를 이용할 경우 변수에 신경 쓰지 않고도 메시지를 변경할 수 있습니다(그 반대도 마찬가지).

또한 숫자는 선택사항이므로 다음과 같이 작성할 수도 있다는 점에 유의합니다.

age = 20
name = 'Swaroop'

print('{} was {} years old when he wrote this book'.format(name, age))
print('Why is {} playing with that python?'.format(name))

이렇게 작성해도 이전 프로그램과 정확히 동일한 결과가 출력됩니다.

또한 매개변수에 이름을 줄 수도 있습니다.

age = 20
name = 'Swaroop'

print('{name} was {age} years old when he wrote this book'.format(name=name, age=age))
print('Why is {name} playing with that python?'.format(name=name))

이번에도 마찬가지로 이전 프로그램과 정확히 동일한 결과가 출력됩니다.

파이썬 3.6에서는 "f-string"이라고 하는 더 짧은 버전의 이름 매개변수(named parameter)가 도입됐습니다.

age = 20
name = 'Swaroop'

print(f'{name} was {age} years old when he wrote this book')  # 문자열 앞에 'f'가 있음
print(f'Why is {name} playing with that python?')  # 문자열 앞에 'f'가 있음

위 코드를 실행해도 이전 프로그램과 정확히 동일한 결과가 출력됩니다.

format 메서드에서 파이썬이 하는 일은 각 인수의 값을 서식 명세가 있는 곳에다 바꿔넣는 것입니다. 다음과 같이 서식 명세를 더 자세하게 지정할 수도 있습니다.

# 정밀도가 3인 부동 소수점 수(.): '0.333'
print('{0:.3f}'.format(1.0/3))
# 텍스트를 가운데에 두고(^) 언더스코어(_)로 채운
# 너비가 11자인 문자열: '___hello___'
print('{0:_^11}'.format('hello'))
# 키워드로 값을 지정한 문자열: 'Swaroop wrote A Byte of Python'
print('{name} wrote {book}'.format(name='Swaroop', book='A Byte of Python'))

출력 결과는 다음과 같습니다.

0.333
___hello___
Swaroop wrote A Byte of Python

지금은 형식화(formatting)에 관해 이야기하는 중이므로 print가 항상 보이지 않는 "개행 문자"(\n)로 끝나서 print를 호출할 때마다 줄을 바꿔서 출력된다는 점에 유의합니다. 출력 결과에서 이러한 개행 문자를 사용하지 않으려면 end 인수에 빈 값을 넣어서 각 줄을 끝내면 됩니다.

print('a', end='')
print('b', end='')

출력 결과는 다음과 같습니다.

ab

또는 end에 공백을 넣어서 각 줄을 끝내도 됩니다.

print('a', end=' ')
print('b', end=' ')
print('c')

출력 결과는 다음과 같습니다.

a b c

이스케이프 시퀀스

작은따옴표(')가 포함된 문자열이 필요하다면 이 문자열을 어떻게 만들어야 할까요? 가령 문자열이 "What's your name?"이라고 해봅시다. 이 경우 'What's your name?'으로 만들 수는 없는데 문자열이 어디에서 시작하고 어디에서 끝나는지 파이썬이 혼동할 것이기 때문입니다. 따라서 이 작은따옴표가 문자열의 끝을 가리키는 게 아니라는 점을 나타내야 할 것입니다. 이때 이스케이프 시퀀스(escape sequence)라는 것을 이용하면 됩니다. 이스케이프 시퀀스로 작은따옴표는 \'라고 쓰면 됩니다(백슬래시에 주목하세요). 그럼 문자열을 'What\'s your name?'으로 만들면 됩니다.

이 같은 문자열을 만드는 또 한 가지 방법은 큰따옴표를 사용해 "What's your name?"로 만드는 것입니다. 이처럼 큰따옴표로 감싼 문자열 내에서 큰따옴표 자체를 사용하려면 이스케이프 시퀀스를 사용해야 합니다. 또한 백슬래시 자체를 나타내려면 \\라는 이스케이프 시퀀스를 사용합니다.

두 줄짜리 문자열을 만들고 싶다면 어떻게 해야 할까요? 한 가지 방법은 앞에서 살펴본 것처럼 삼중따옴표 문자열을 이용하는 것입니다. 아니면 개행 문자에 해당하는 이스케이프 시퀀스인 \n을 이용해 새로운 줄이 시작된다는 것을 나타낼 수 있습니다. 다음 예제를 봅시다.

'This is the first line\nThis is the second line'

또 한 가지 알아두면 유용한 이스케이프 시퀀스는 탭(\t)입니다. 이 밖에도 다양한 이스케이프 시퀀스가 있지만 여기서는 가장 유용한 것들만 알아봤습니다.

한 가지 알아둘 만한 것은 줄 끝에 백슬래시 하나를 넣으면 개행 문자가 추가되지 않고 문자열이 다음 줄과 이어진다는 것입니다. 다음 예제를 봅시다.

"This is the first sentence. \
This is the second sentence."

위 문자열은 다음 문자열과 같습니다.

"This is the first sentence. This is the second sentence."

원시 문자열

이스케이프 시퀀스 같은 특별한 처리가 이뤄지지 않는 문자열이 필요하다면 문자열 앞에 r이나 R을 지정해 원시(raw) 문자열로 만들면 됩니다. 다음 예제를 봅시다.

r"Newlines are indicated by \n"

정규 표현식 사용자를 위한 메모

정규 표현식(regular expression)을 다룰 때는 항상 원시 문자열을 사용하세요. 그렇지 않으면 정규 표현식이 백슬래시 투성이가 될지도 모릅니다. 예를 들면, 역참조는 '\\1'이나 r'\1'로 나타낼 수 있습니다.

변수

리터럴 상수만 사용하는 것은 금방 지루해질 수 있습니다. 정보를 저장하고 조작하는 다른 방법이 필요합니다. 이때 변수(variable)를 사용하는 것을 생각해볼 수 있습니다. 이름이 의미하는 것처럼 변수의 값은 변경될 수 있습니다. 즉, 변수를 이용해 무엇이든 저장할 수 있습니다. 변수는 정보를 저장하는 컴퓨터 메모리의 일부분에 불과합니다. 리터럴 상수와 달리 이러한 변수에 접근하려면 어떤 방법이 필요하며, 따라서 변수에는 이름을 부여합니다.

식별자 이름 짓기

변수는 식별자의 한 예입니다. 식별자(identifier)란 무언가를 구별하기 위해 부여하는 이름입니다. 다음은 식별자에 이름을 부여할 때 따라야 할 몇 가지 규칙입니다.

  • 식별자의 첫 글자는 알파벳 문자(대문자 ASCII 문자나 소문자 ASCII 문자, 혹은 유니코드 문자)나 언더스코어(_)여야 합니다.
  • 식별자명의 나머지는 문자(대문자 ASCII 문자나 소문자 ASCII 문자, 혹은 유니코드 문자)나 언더스코어(_), 숫자(0-9)로 구성할 수 있습니다.
  • 식별자명은 대소문자를 구분합니다. 예를 들어, mynamemyName은 같지 않습니다. 전자의 소문자 n과 후자의 대문자 N에 주의하세요.
  • 유효한 식별자명의 예로 i, name_2_3을 들 수 있습니다. 유효하지 않은 식별자명의 예로 2things, this is spaced out, my-name, >a1b2_c3를 들 수 있습니다.

데이터 타입

변수는 데이터 타입(data type)이라고 하는 다양한 유형의 값을 담을 수 있습니다. 기본적인 타입으로 앞에서 살펴본 숫자, 문자열이 있습니다. 이후 장에서는 클래스(class)를 이용해 직접 타입을 만드는 법을 알아보겠습니다.

객체

파이썬은 프로그램 내에서 사용된 모든 것들을 객체(object)로서 참조하며, 기본적으로 파이썬에서는 그렇게 하도록 돼 있습니다. 따라서 이 책에서도 "그것(something)"이라고 표현하는 대신 "객체(object)"라고 표현하겠습니다.

객체지향 프로그래밍 사용자를 위한 메모:

파이썬에서는 숫자, 문자열, 함수를 비롯해 모든 것이 객체라는 점에서 대단히 객체지향적입니다.

이제 리터럴 상수를 비롯해 변수를 어떻게 사용하는지 알아보겠습니다. 아래에 나오는 예제를 저장하고 프로그램을 실행해 봅시다.

파이썬 프로그램을 작성하는 법

이후로 파이썬 프로그램을 저장하고 실행하는 표준 절차는 다음과 같습니다.

PyCharm을 사용하는 경우

  1. PyCharm을 엽니다.
  2. 지정한 파일명으로 새 파일을 생성합니다.
  3. 예제 코드를 입력합니다.
  4. 마우스 오른쪽 버튼을 클릭한 후 현재 파일을 실행합니다.

참고: 명령줄 인수(command line arguments)를 넣어야 하는 경우 RunEdit Configurations를 차례로 클릭한 후 Script parameters:란에 인수를 입력하고 OK 버튼을 클릭합니다.

PyCharm command line arguments

다른 편집기를 사용하는 경우

  1. 선택한 편집기를 엽니다.
  2. 예제 코드를 입력합니다.
  3. 지정한 파일명으로 파일을 저장합니다.
  4. python program.py 명령으로 인터프리터를 실행해 프로그램을 실행합니다.

예제: 변수와 리터럴 상수 사용하기

다음 프로그램을 입력하고 실행합니다.

# 파일명: var.py
i = 5
print(i)
i = i + 1
print(i)

s = '''This is a multi-line string.
This is the second line.'''
print(s)

출력 결과는 다음과 같습니다.

5
6
This is a multi-line string.
This is the second line.

동작 원리

이 프로그램이 동작하는 방식을 설명하겠습니다. 먼저 할당 연산자(=)를 이용해 리터럴 상수 값인 5i 변수에 할당합니다. 이 줄을 문장(statement)이라고 하는데, 문장에 어떤 일을 수행할지 적혀 있기 때문입니다. 여기서는 변수명 i를 값 5에 연결합니다. 다음으로 print 문을 이용해 i의 값을 출력하는데, 당연히 해당 변수의 값이 화면에 출력됩니다.

그런 다음 i에 저장된 값에 1을 더해서 다시 저장합니다. 그리고 그것을 출력하고, 예상했다시피 6이라는 값을 얻습니다.

이와 마찬가지로 리터럴 문자열을 s 변수에 할당한 후 출력합니다.

정적 언어 프로그래머를 위한 메모

파이썬에서는 변수에 값을 할당하기만 해도 변수를 사용할 수 있습니다. 변수를 선언하거나 데이터 타입을 정의할 필요도 없고 그렇게 하지도 않습니다.

논리적 라인과 물리적 라인

물리적 라인은 프로그램을 작성할 때 보게 되는 것입니다. 논리적 라인은 파이썬이 하나의 문장으로 보는 것입니다. 파이썬은 내부적으로 각 물리적 라인논리적 라인에 상응한다고 가정합니다.

논리적 라인의 한 가지 예는 print('hello world') 같은 문장입니다. 만약 이 코드가 그 자체로 한 줄을 차지한다면(편집기에서 보는 바와 같이) 물리적 라인과도 상응합니다.

암묵적으로 파이썬은 가독성 향상을 위해 한 줄에 하나의 문장을 사용하는 것을 권장합니다.

한 줄의 물리적 라인에 여러 논리적 라인을 지정하고 싶다면 논리적 라인/문장의 끝을 나타내는 세미콜론(;)을 이용해 이를 명시적으로 나타내야 합니다. 다음 예제를 봅시다.

i = 5
print(i)

위 코드는 사실상 다음 코드와 같습니다.

i = 5;
print(i);

또한 다음 코드와도 같습니다.

i = 5; print(i);

아래 코드도 마찬가지입니다.

i = 5; print(i)

하지만 물리적 라인마다 최대 한 줄의 논리적 라인을 작성하길 적극 권장합니다. 이는 세미콜론을 써서는 안 된다는 것을 의미합니다. 사실 저는 파이썬 프로그램에서 한 번도 세미콜론을 써보거나 본 적조차 없습니다.

이 개념이 실제로 유용한 상황이 한 가지 있습니다. 코드가 긴 경우 백슬래시를 이용해 여러 줄의 물리적 라인으로 쪼갤 수 있습니다. 이를 명시적 라인 결합(explicit line joining)이라 합니다.

s = 'This is a string. \
This continues the string.'
print(s)

출력 결과는 다음과 같습니다.

This is a string. This continues the string.

이와 비슷하게 다음 코드는

i = \
5

다음 코드와 같습니다.

i = 5

간혹 백슬래시를 사용하지 않아도 되는 경우가 있습니다. 바로 논리적 라인에 괄호나 대괄호, 중괄호를 열고 나서 닫지 않는 경우입니다. 이를 암묵적 라인 결합(implicit line joining)이라 합니다. 이후 장에서 리스트(list)를 이용해 프로그램을 작성할 때 실제로 볼 수 있습니다.

들여쓰기

공백(whitespace)은 파이썬에서 중요합니다. 실제로 라인의 맨 앞에 있는 공백(whitespace)이 중요합니다. 이를 들여쓰기(indentation)라 합니다. 논리적 라인의 맨 앞에 놓인 선행 공백(스페이스와 탭)은 논리적 라인의 들여쓰기 수준을 결정하는 데 사용되며, 결과적으로 문장 그룹을 파악하는 데 사용됩니다.

이것은 하나로 묶어야 할 문장들은 들여쓰기도 반드시 동일해야 한다는 뜻입니다. 이 같은 문장의 집합을 각각 블록(block)이라 합니다. 이후 장에서 블록이 얼마나 중요한지를 보여주는 예제를 보게 될 것입니다.

한 가지 기억해야 할 점은 들여쓰기를 잘못할 경우 오류가 발생할 수 있다는 것입니다. 다음 예제를 봅시다.

i = 5
# 아래 코드에서 오류가 발생합니다! 라인 맨 앞에 공백이 하나 있습니다.
 print('Value is', i)
print('I repeat, the value is', i)

이 프로그램을 실행하면 다음과 같은 오류가 발생합니다.

  File "whitespace.py", line 3
    print('Value is', i)
    ^
IndentationError: unexpected indent

두 번째 줄의 맨 앞에 공백이 하나 있다는 데 유의합니다. 파이썬에서 보여주는 오류의 의미는 프로그램이 파이썬 문법에 맞지 않다는 것입니다. 즉, 프로그램이 적절하게 작성되지 않았다는 뜻입니다. 오류의 의미는 임의로 새로운 문장 블록을 시작할 수 없다는 것입니다(물론 지금까지 사용해온 기본 메인 블록은 제외). 새로운 블록을 사용할 수 있는 경우에 대해서는 제어 흐름(control flow)과 같은 이후 장에서 자세히 다루겠습니다.

들여쓰기하는 방법

들여쓰기할 때는 공백 4칸을 사용하세요. 이는 파이썬 언어에서 공식적으로 권장하는 바입니다. 훌륭한 편집기라면 이를 자동으로 처리할 것입니다. 들여쓰기를 위한 공백 개수를 일관되게 유지해야 하고, 그렇지 않으면 프로그램이 실행되지 않거나 예상치 못한 방식으로 동작할 것입니다.

정적 언어 프로그래머를 위한 메모

파이썬에서는 언제나 블록에 들여쓰기를 사용하고 중괄호를 쓰지 않습니다. 더 자세한 사항이 궁금하다면 from __future__ import braces를 실행해 보세요.

정리

지금까지 파이썬의 여러 핵심적인 내용들을 살펴봤으므로 이제 제어문과 같은 좀 더 흥미로운 주제로 넘어갈 수 있습니다. 이번 장에서 읽은 내용들을 숙지하길 바랍니다.