콘텐츠로 건너뛰기
Home » Python 101 : 출력과 문자열 (1)

Python 101 : 출력과 문자열 (1)

10년전에 작성했던 파이썬 강좌글을 틈틈히 최신 버전에 맞게 수정하고 내용을 수정/보강하여 재발행하는 글입니다. 만성적인 귀찮음 때문에 연재도 중간에 그냥 그만두었었는데, 이번에는 언제까지 해 나갈 수 있을까요?

어떤 프로그래밍 언어를 공부하든간에 거의 가장 처음 접하게 되는 것이 어떤 값을 화면에 출력해보는 것입니다. 사실 출력과 관련된 부분에 대해서도 좀 알아두어야 할 것이 많지만 다른 것들은 뒤로 미루고 오늘은 간단하게 출력만 하는 것에 대해서 살펴보고자 합니다. 왜냐하면 코드 너머에서 실제로 벌어지고 있는 일들은 우리 눈에 보이지 않기 때문에 “코드가 제대로 실행되는지”, “값은 제대로 계산되는지” 같은 궁금한 점을 확인해 볼 수 있는 유일한 방법은 어떤 값을 화면에 찍어보는 것이 가장 빠르고 확실하기 때문이죠. 그러니 다른 어떤 것을 해보기 이전에 무언가를 화면에 찍어볼 수 있는 것이야 말로 가장 먼저 익혀 두어야 하는 테크닉입니다.

그래서 파이썬을 처음 시작하는 사람을 위해서 소개할 첫번째 함수는 바로 print()가 됩니다. 물론 이쯤에서 함수가 무엇인지…같은 걸 설명하는 게 빠진 것 같지만, 그것은 기분 탓이니까 우선은 넘어가도록 합니다. 아직 아무것도 시작하지 않았는데, 함수가 무엇인지 설명하는 것은 지금으로서는 의미가 없을테니까요.

print() 함수는 전달받은 값을 화면에 출력해주는 기능입니다. 값을 출력할 때에는 자동으로 줄바꿈 문자를 덧붙이기 때문에, 이 함수를 여러번 사용하면 마치 한 번에 한줄씩 출력하는 것처럼 보입니다. 어떤 ‘단어’를 출력해보고 싶다면, 문자열을 그대로 사용하면 되는데, 문자열이라는 것을 사용하려면 보통 따옴표를 사용합니다. "hello" 라든지, 'world' 와 같은 식으로요. 그외에 숫자값이나, 어떤 변수의 값을 출력하는 것도 가능합니다.

print(1)
# => 1

print("hello")
# => hello

a = 3 + 5
print(a)
# => 8

print() 함수에는 한꺼번에 여러 개의 값을 전달해서 한 줄에 출력할 수 있습니다. 이 때 각 값은 콤마를 사용하여 구분해줍니다. 기본적으로 print() 에서는 콤마로 구분된 값을 한 칸의 공백으로 구분하여 출력해줍니다.

print(1, "hello")
# => 1 hello
print("number:", 1, "|", "greet:", "'hello'")
# => number: 1 | greet: 'hello'

변수 출력하기

앞에서 출력해본 예제에서는 출력에 사용했던 1 이나 "hello" 는 모두 ‘상수표현’입니다. 이렇게 상수 표현 외에 변수 이름을 넣으면 그 변수가 가리키는 값을 출력해 볼 수 있습니다. 그 외에 계산식을 바로 넣어서 출력하는 것도 가능합니다.

a = 1
print(a)
# => 1
print(a + a)
# => 2
print(a + a + a, a * 4)
# => 3 4

변수를 사용하는 방식이 상수와 같아서 시시해 보일 수도 있는데, 사실 print() 함수의 가장 주된 목적이 바로 변수값을 확인하는 것이라고 생각합니다. 다음은 1에서 10까지의 자연수를 모두 더한 뒤에 그 결과를 표시해주는 코드입니다.

a = 0
for i in range(1, 11):
  a = a + i
print("1~10의 합:", a)

문자열

print(1)print("hello") 의 차이점은 무엇일까요? 다른 것은 1"hello" 이므로 이 질문은 결국 이 둘의 차이를 묻는 것과 같습니다.1 정수(int) 타입의 값으로 우리가 잘 알고 있는 ‘한 개’를 표현하는 1이라는 정수값을 나타내는 표현입니다. 그리고 "hello"h, e, l, l, o 이렇게 다섯 개의 알파벳 글자가 모여서 만들어진 “문자열”입니다. 프로그래밍 언어에 따라서는 낱개의 문자와 문자열을 다르게 취급하는 언어들도 있습니다만, 파이썬에서는 이를 구분하지 않고 글자 수에 상관없이 모두 “문자열”로 취급합니다.

프로그래밍에서 문자열은 매우 중요한 자료형입니다. 컴퓨터에서 각각의 문자는 내부적으로 어떤 숫자값으로 표현됩니다. 이를 테면 대문자 A 는 숫자 65로 표현하기로 하고, 소문자 a 는 97이라는 값으로 표현하는 것이죠. 숫자를 문자로 표현하고 이를 여러 사람에게 똑같이 표현하려면 이러한 글자와 숫자값의 관계를 미리 약속해 놓는 것이 필요합니다. 이러한 관계 중 가장 유명한 것이 “아스키 코드”입니다. 아스키 코드는 127개의 흔히 쓰는 문자들을 숫자에 할당해놓은 것입니다. 영어 알파벳 대소문자와 숫자, 그리고 기본적인 문장 부호와 컴퓨터가 화면에 글자를 처리할 때 사용하는 특수한 기호들까지 여기에 포함되어 있습니다.

다만 이정도의 약속은 전세계에서 통용되는 다양한 언어와 거기에 사용되는 문자를 모두 표현하기에는 턱없이 부족합니다. 그래서 전세계의 컴퓨터 과학자들과 언어학자들이 모여서 ‘유니코드’라는 것을 제정했습니다. 말 그대로 하나의 코드표만 가지고 모든 문자를 표현하자는 약속을 만드는 것이죠. 이 문자표의 스케일은 어마어마하게 크기 때문에 현재 지구상에서 사용되는 혹은 사용되었던 모든 언어의 문자를 다 포함하고도 남을 정도 입니다. 딩벳이라 불리는 장식 문자는 물론 각종 학문에서 쓰이는 기호, 점자 언어 문자는 물론 외계인의 문자가 있다면 그것도 다 여기에 넣어줄 정도로 거대한 체계입니다.

2022년을 기준으로 현재 파이썬의 최신 버전은 3.10이며 (10월에 3.11이 발표될 예정입니다.) 파이썬 3부터는 파이썬 소스코드 및 파이썬 문자열은 모두 유니코드로 취급됩니다. (아주 오래된 코드에서 보이는 -*-coding: utf-8 같은 건 사실 10년 전부터 안써도 되는 것들이에요.)

출력에 대한 이야기를 하다가 너무 멀리 가버렸네요. 사실 print() 함수가 출력하는 값들은 모두 문자열입니다. 하지만 앞서 봤듯이 정수와 같이 문자열이 아닌 값들도 이 함수를 사용하면 출력이 가능합니다. 심지어 일상적으로 상상할 수 있는 그런 타입이 아닌 객체들도 출력이 가능합니다. 이것은 각각의 값들이 자기 스스로를 문자열로 표현하는 방법을 알고 있기 때문에 가능한 일입니다. 정수 1 은 자기 스스로를 문자열로 표현했을 때, "1" 이 된다는 사실을 알고 있어요. 그래서 print() 가 실제로 실행될 때에는 넘겨지는 모든 값들에 대해서 파이썬은 “너를 문자열로 표현하여라”하는 요청을 각 값들에게 하게 됩니다. 그리고 그 결과를 화면에 출력하는 것이지요.

파이썬에서 문자열을 만드는 방법

파이썬에서 문자열을 만드는 문법을 간단히 소개합니다. 모두 외워둘 필요는 없겠습니다. " ... ", ' ... ' 을 기본으로 하되, 몇 가지 추가적인 테크닉이 포함된다..는 거 정도만 알고 넘어가면 되겠습니다.

  • 겹따옴표로 둘러싼 영역은 문자열이다. ("hello")
  • 홑따옴표로 둘러싼 영역은 문자열이다. ('hello')
  • 겹따옴표 세 개, 홑따옴표 세 개로 둘러싼 영역을 만들 수 있는데, 재밌는 점은 삼중 따옴표로 둘러싼 영역은 중간에 엔터를 눌러서 여러줄에 걸펴서 작성할 수 있으며, 이 때에는 문자열에 줄바꿈문자까지 포함되어 만들어진다. 출력해야 할 내용이 여러줄로 길 때 사용하기에 적절하다.
  • 따옴표 앞에 r 을 붙이면 raw 문자열을 만든다. 음.. raw 문자열은 백슬래시(\) 문자를 포함해야 할 때, 백슬래시를 입력하는 횟수를 줄이는 용도로 사용하는데, 정규식을 생성할 때 사용한다.(고 알고 있으면 되겠다.)
  • 따옴표 앞에 b를 붙이면 바이트배열을 만든다. 역시 지금은 이런 것이 있구나 정도로 생각하면 된다.
  • 따옴표 앞에 f를 붙이면 포맷팅 문자열을 만든다. 조만간에 좀 더 자세히 살펴보게 될 것이다.

참고로, 이렇게 따옴표 기호를 사용해서 입력한 코드 그 자체가 어떤 값이 되도록 하는 표현을 “리터럴”이라고 합니다. 이 말이 “표기법”하고 정확하게 대응하는 말인지는 모르겠는데, 문법으로 정의되어 있는 표기법이다… 하는 정도로 알고 넘어가면 됩니다.

조금 더 자세히 살펴보는 print() 함수

print() 함수에 여러 개의 값을 전달하면 공백으로 구분하여 출력해준다고 했습니다. 그리고 print() 함수는 끝에 줄바꿈을 삽입하기 때문에 한 번에 한 줄에 걸쳐서 값을 출력한다고도 했습니다. 사실 이러한 동작들은 ‘조정(?)’이 가능합니다. 값을 출력할 때, 몇 가지 옵션을 주어서 표시하는 방식을 변경할 수 있습니다. print() 함수의 실제 정의는 다음과 같습니다.

def print(*objects, sep=" ", end="\n", file=sys.stdout, flush=False):
  ...

여기서 *objects 라고 되어 있는 부분은 콤마를 사용해서 넘겨준 출력할 값들을 의미합니다. 그 뒤에는 출력 동작의 세부적인 설정과 관련된 값들이 있습니다. 이 전부를 이 자리에서 설명할 필요는 없을 것 같습니다. 궁금하다면 표준 문서 를 찾아보는 것도 좋겠네요. sep=" " 이라고 표시된 부분은 각각의 값들을 공백으로 구분한다는 의미입니다. 그리고 end="\n" 는 출력의 끝에는 자동으로 개행문자를 붙이겠다는 의미입니다. 만약 print(1, 2, 3, 4, sep=", ") 이라고 호출한다면 "1, 2, 3, 4"와 같이 각각의 값이 ", " 로 구분되어 출력될 것입니다. 그리고 end="" 를 써준다면, 다음 번 출력 시에는 줄바꿈 없이 바로 다음 글자 위치에 이이서 내용이 출력될 것입니다.

하지만 이 부분은 그냥 이런게 있다… 정도로 알고 넘어가면 되겠습니다. 왜냐하면 이 방식으로 출력되는 모양을 조정하는 것은 별로 깔끔하지도 않고, 표시하려는 데이터가 많고 레이아웃이 복잡할수록 정확하게 표현하기가 점점 더 어려워지는 문제가 있을 것이거든요.

오늘은 간단하게 여기서 마무리하도록 하고, 다음 기회에는 조금 더 복잡한 출력 양식을 어떻게 구현하는지에 대해서 배워보도록 하겠습니다.