[파이썬 튜토리얼] print('Hello, world!')

Photo by Jon Tyson on Unsplash

[파이썬 튜토리얼] print('Hello, world!')

·

7 min read

이제 파이썬 프로그래밍을 시작해 보도록 하자. 첫 단원에서는, 제목처럼 print('Hello, world!')라는 한 줄의 파이썬 코드를 실행해볼 것이다. 이는 Hello, world!라는 텍스트를 터미널에 표시하는 내용의 코드다.

Level 1

코드 입력하기

앞 단원에서 생성한 모듈에, 다음 코드 한 줄을 입력하자.

print('Hello, world!')

만들었던 모듈을 우클릭한 후, 초록색 아이콘과 함께 Run 키워드가 있는 항목을 클릭하면 코드가 실행된다.

hello-world-execute.png

실행 결과를 보여주기 위한 창이 하단에 노출되고, Hello, world!가 성공적으로 출력된 것을 볼 수 있다.

hello-world-execute-result.png

이번 단원의 목표인 Hello, world! 출력에 성공했다. print라는 키워드 뒤에 소괄호를 열고, 작은따옴표 사이에 내용을 입력하고, 소괄호를 닫으면 그 내용을 그대로 출력해준다는 것을 알 수 있었다. print가 가진 출력이라는 뜻 그대로 이해하면 된다.

실행문 여러 개 두기

실행문을 여러 개 두려면, 새로운 줄에 그 내용을 작성하면 된다.

print('hello')
print('world')

결과

hello
world

빈 줄

파이썬에서 빈 줄은 실행 결과에 영향을 미치지 않는다.

print('hello')



print('world')

결과

hello
world

조언

  • print라는 것을 통해 텍스트를 출력할 수 있다는 것과, 모듈 생성부터 코드 실행 과정까지의 흐름을 대략 이해했다면 넘어가자. 모든 단계들을 암기하려고 할 필요는 없다. 프로그래밍을 하면서, 이미 배웠던 내용을 다시 검색하는 과정은 자연스러운 현상이다.
  • 궁금한 게 있다면 바로 시도해 보자. 아무 내용도 없는 모듈을 실행하거나, 아무 내용도 없는 print문을 실행하는 것을 예로 들 수 있다. 프로그램 실행에 실패하거나, 에러가 난다고 해서 컴퓨터가 고장나는 것이 아니니 상상만 하지 말고 직접 경험해 보자.

자투리 지식

.py와 확장자

파이썬 모듈을 생성할 때, 그 이름 뒤에 자동으로 붙는 .py는 해당 파일이 파이썬 파일임을 의미한다. .txt가 텍스트 파일임을, .png.jpg 등이 이미지(사진) 파일임을 나타내는 것과 같은 맥락이다. 이렇게 파일 이름의 마지막 점(.) 뒤에 나타나는 부분을 확장자(extension)라고 부르며, 파일의 종류나 역할을 설명하기 위한 파일명의 일부다.

확장자는 보통 파일에 대한 연관 작업을 결정하는 데에 사용된다. .txt 확장자의 파일을 열었을 때는 메모장이, .py 확장자의 파일을 열었을 때는 PyCharm이 열리는 것을 예로 들 수 있다. 확장자는 단순히 파일명의 일부이기 때문에, 확장자를 변경한다고 해서 파일의 내용이 바뀌는 것은 아니다. 만약 어느 파일의 확장자가 .txt더라도, 그 내용이 파이썬 코드로 이루어져 있다면 파이썬 인터프리터를 통해 실행할 수 있다.

그러나 .py 확장자를 가지지 않은 파일은, 그 내용이 파이썬 코드로 이루어져 있더라도 제대로 해석되지 못할 수 있다. .py 확장자 외의 파일은 파이썬 모듈로 인정되지 않기 때문이다. 단순히 실행하는 수준까지는 큰 문제가 없더라도, 더 복잡한 상황에서는 문제가 발생할 수 있다. 따라서 파이썬 코드로 이루어진 파일에는 .py 확장자를 붙여 해당 파일이 파이썬 파일임을 의미하도록 하는 것이 좋다.

CLI

Windows의 명령 프롬프트(cmd), Mac의 Terminal로 대표되는 CLI(Command Line Interface)는 명령어를 입력하고 그 결과를 제공받는 형태로 컴퓨터를 조작하는 방식을 아우른다. 예로, 바탕 화면에서 우클릭을 통해 폴더(디렉토리)를 생성하고 삭제하는 동작은 CLI에서 각각 mkdirrmdir 명령어로 표현할 수 있다.

명령어를 이용해 컴퓨터를 조작하는 방식은 생소하고 원시적이지만, 그래픽 인터페이스가 없던 때에는 명령어를 통해서만 컴퓨터를 조작할 수 있었다. 따라서 프로그래밍 언어는 CLI에서 구동되는 프로그램을 개발할 수 있게 해주는 것이 기본이다. 이번 단원에서 배운 파이썬의 print가 그 예다.

다음은 이번 단원의 범위를 벗어나지만, CLI를 통해 입력받은 값에 알파벳 a가 들어있는지를 출력하는 예제다. CLI는 입력과 출력을 기반으로 동작하므로, 파이썬을 이용한 입력과 출력을 알아볼 수 있도록 덧붙였다. 프로그램을 실행하고, 활성화된 터미널에 숫자 값을 입력하면 그 결과를 얻을 수 있다.

x = input()

print('a' in x)

입력

hola

결과

True

CLI는 모든 상호작용이 텍스트만으로 이루어지는 만큼, 프로그래밍 언어로 조작하기 쉽다. 예를 들어 print를 통해 CLI로 결과를 출력하는 것이, 어떤 창을 띄워 결과를 제공하는 것보다 간단하다. 이 때문에 프로그래밍 언어를 처음 배울 때 CLI를 주로 사용하는 것이고, 앞으로 작성될 거의 모든 예제도 CLI의 범위에서 벗어나지 않을 것이다. CLI를 보통 터미널(Terminal), 콘솔(Console), tty 등의 이름으로 부르는데, 책에서는 터미널로 통일한다.

"Hello, world!" 예제의 시작

프로그래밍과 관련된 분야의 첫 단계에서, hello world를 출력하는 것을 첫 단계로 두는 경우가 많다. 특수문자의 사용 여부, 대소문자 등 구체적인 부분은 예제마다 다르더라도 helloworld가 포함되는 것은 항상 동일하다. C언어 입문서인 The C Programming Language(약칭 TCPL)의 첫 번째 예제는 터미널에 "Hello, world!"를 출력하는 것이었는데, 이것이 유명해지면서 예제로 자주 사용되기 시작한 것이다.

TCPL의 저자 중 한 명인 브라이언 커니핸이 TCPL 이전에 집필한 에서 가장 최초로 helloworld를 같이 사용한 예제가 작성되었다. 이후 커니핸이 작성한 매뉴얼인 의 예제를 TCPL이 물려받았다. 개정판에 따라 조금씩 모양은 달라지는데, 대체적으로 다음과 같은 모양이다.

#include <stdio.h>

int main()
{
    printf("Hello, world!\n");
    return 0;
}

Level 2

print가 개행을 일으키지 않게 하기

두 번의 print문이 있을 때, 각각의 내용은 개행(줄 바꿈) 기준으로 나뉘어 출력된다.

print('hello')
print('world')

결과

hello
world

이는 print에 내용을 출력한 뒤 개행을 일으키는 기능이 포함되어 있기 때문이다. print가 개행을 일으키지 않게 하려면, print문을 다음처럼 작성하면 된다.

print('hello', end='')
print('world')

결과

helloworld

출력하고자 하는 내용 뒤에 콤마(,)를 작성하고, end=''라는 내용을 입력해 주면 된다.

파이썬 파일의 이름을 짓는 관례

파이썬 파일은 한글, 알파벳, 숫자, 특수문자 등 여러 종류의 문자를 사용해 이름지을 수 있다. 그러나 아무 문자나 사용해서 이름을 짓게 되면 나중에 문제가 생길 수 있다. 예를 들어 hypen(-)이 포함된 이름은 해당 기호가 파이썬에서 뺄셈을 나타내므로, 제대로 사용하지 못할 수 있다. 이름을 짓는 과정을 네이밍(Naming)이라 말하고, 그 규칙을 네이밍 관례(Naming Convention)이라 말한다. 다음은 파이썬 파일에 대해 공식적으로 권장되는 네이밍 관례다.

  • '영어 소문자로 이루어진 짧은 이름'을 사용한다. 영단어 하나 정도라고 생각하면 된다.
  • 그 정도로 짧게 표현하기 어렵다면, 단어 여러 개를 언더스코어로 이어붙여 이름짓는다.

실습 과정에서 이러한 관례를 무조건 지킬 필요는 없지만, 대부분의 파이썬 개발자들이 이 규칙을 지키고 있으니 알고 넘어가도록 하자.

세미콜론

앞에서, 실행문을 여러 개 두기 위해서는 매번 새로운 줄에 그 내용을 작성해야 한다고 했다. 파이썬 코드에서 줄 바꿈은 실행문의 종료를 의미하기 때문이다.

print('hello') print('world')

결과

  File "example.py", line 1
    print('hello') print('world')
                   ^
SyntaxError: invalid syntax

세미콜론(;)을 통해 실행문의 종료를 직접 명시할 수 있다. 이 경우, 새로운 실행문을 뒤에 이어서 둘 수 있다.

print('hello'); print('world')

결과

hello
world

파이썬 프로그래밍을 하는 과정에서 세미콜론이 사용되는 경우는 거의 없다. 세미콜론을 붙인다고 에러가 나진 않지만, 붙이지 않는 것이 일반적이다.

행간 결합

명시적 행간 결합

여러 줄에 걸쳐 작성된 내용을, 마치 한 줄에 있는 것처럼 만들 수 있다. 문장의 끝에 backslash() 기호가 있다면, 다음 줄에 이어지는 내용이 현재 줄에 결합된다.

print(\
'hel\
lo'\
)

결과

hello

위 코드는 print('hello')로 해석된다. 이를 명시적 행간 결합이라고 말한다. 실행문 하나를 한 줄로 나타내기에 너무 길어진다면, 이렇게 backslash 기호를 사용해 여러 행으로 나누어볼 수 있다.

비명시적 행간 결합

backslash 없이도 행간 결합이 이루어지는 경우가 있다. 실행문의 중간에 괄호가 열리는 경우, 괄호를 닫을 때까지의 행이 모두 결합되어 하나의 실행문으로 간주된다. 괄호 외에도 비명시적 행간 결합이 생기는 경우가 종종 있다.

print(
    'hello'
)

결과

hello

print는 함수다

앞의 print처럼, 이름 뒤에 소괄호를 열고 값을 쥐어줬을 때, 정해진 코드를 실행하는 주체를 함수라고 부른다. 간단하게 생각하면, 코드 뭉치에 이름을 지어놓은 것이다. 파이썬이 자체적으로 제공하는 print와 같은 함수를 빌트인 함수라고 부르고, 뒤에서 함수에 대해 배우고 나면 직접 함수를 만들어볼 수도 있게 될 것이다.

Level 3

print 함수의 시그니처

print 함수의 시그니처는 print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)다. 실행 흐름은 다음과 같다.

  1. 가변 길이 위치 인자인 objects로 전달된 요소 각각의 사이에 sep을 끼워넣는다.
  2. end를 맨 뒤에 붙인다.
  3. 이 내용을 filewrite 메소드 호출에 인자로 사용한다.

따라서, 다음 예제의 3, 4번 라인에 작성된 두 실행문은 동일한 의미를 갖는다.

import sys

print('a', 1, 2, sep='.', end='!')
sys.stdout.write('a.1.2!')

결과

a.1.2!a.1.2!

출력할 내용은 file 매개변수로 넘어온 객체의 write 메소드로 전달되기 때문에, write 메소드가 정의되어 있는 파일 객체에 print 함수를 응용할 수도 있다. 예로, 다음 예제를 실행하면 내용으로 hi라는 텍스트가 적힌 test.txt 파일이 생성된다.

with open('test.txt', 'w') as f:
    print('hi', file=f)

__str__과 __repr__

print 함수는 전달된 객체의 str 메소드를 호출한 리턴을, 정의되어 있지 않다면 repr 메소드를 호출한 리턴을 사용한다.

class Example1:
    """ __str__만 정의된 클래스 """

    def __str__(self):
        return 'return of __str__'


class Example2:
    """ __repr__만 정의된 클래스 """

    def __repr__(self):
        return 'return of __repr__'


class Example3:
    """ __str__과 __repr__이 모두 정의된 클래스 """

    def __str__(self):
        return 'return of __str__'

    def __repr__(self):
        return 'return of __repr__'


print(Example1())
print(Example2())
print(Example3())

결과

return of __str__
return of __repr__
return of __str__

둘 다 정의되어 있지 않으면 계속해서 상위 클래스로 올라가며 strrepr을 찾는다. 최상위 클래스 objectstrrepr 메소드는 클래스의 위치와 메모리 주소를 리턴하게 되어 있다.

class Example:
    pass


print(Example())
print(Example().__repr__())
print(Example().__str__())

결과

<__main__.Example object at 0x0000018E5F16DFD0>
<__main__.Example object at 0x0000018E5F16DFD0>
<__main__.Example object at 0x0000018E5F16DFD0>