Logo

파이썬의 print() 함수 제대로 활용하기

아마도 파이썬에서 가장 많이 사용되는 내장 함수는 print()일 것 같은데요. 특히 아무리 디버거(debugger)가 좋아지더라도 간단한 버그를 찾을 때 print()로 출력해보는 것만큼 빠르고 간단한 방법도 없습니다.

이렇게 유용하고 많이 사용되는 print() 함수를 어떻게하면 좀 더 잘 활용할 수 있을까요?

기본 출력

제일 먼저 주변에서 print() 함수를 사용하는 가장 흔한 방법을 살펴볼까요?

print("안녕")
print(123)
print([1, 2.5])
print({"이름": None, "관리자": True})
안녕
123
[1, 2.5]
{'이름': None, '관리자': True}

매일 쓰다보니 당연히 받아드려지는 부분이지만 print() 함수는 문자열을 출력하지만 입력으로 문자열을 넘기도록 강제하지는 않습니다. 문자열 타입이 아닌 데이터가 입력으로 들어오면 print() 함수는 내부적으로 넘어온 데이터를 상대로 str() 함수를 호출한 결과를 출력합니다.

예를 들어, print() 함수에 정수가 인자로 넘어오면,

print(123)

실제로는 print() 함수는 다음과 같이 동작하게 됩니다.

print(str(123))

다시 말해, 프로그래머가 str() 함수를 사용하여 직접 해당 정수를 문자열로 변환한 후에 출력하는 것처럼 처리가 됩니다.

사소한 부분으로 느껴질 수도 있지만 이 부분을 간과해서 어려움을 겪는 경우를 자주 보게 됩니다. 대표적으로 다음 섹션에서 설명드린 객체 출력를 들 수가 있습니다.

객체 출력

위와 같이 내장 데이터 타입이 아닌 내가 직접 작성한 클래스로 부터 생성한 객체를 대상으로 print() 함수를 사용하면 어떻게 될까요?

다음과 같이 숫자를 담기위한 간단한 클래스 하나를 작성해보겠습니다.

class NumberHolder:
    def __init__(self, number):
        self.number = number

이 클래스의 인스턴스를 하나 생성하여 print() 함수로 출력을 해볼까요?

print(NumberHolder(1))
<__main__.NumberHolder object at 0x7f6b9d71e990>

흠… 🤔 딱히 도움이 되지 않은 이상한 문자열이 출력이 되네요. 아마도 이 객체를 생성하기 위해 사용된 클래스 이름과 메모리 주소를 나타내는 것 같습니다. 왜 이런 일이 발생하는 걸까요?

이유는 이전 섹션에서 설명드렸듯이 print() 함수에 문자열 타입이 아닌 데이터가 인자로 넘어오면 str() 함수를 내부적으로 호출하기 때문입니다. str() 함수는 인자로 넘어온 객체의 __str__() 매직 함수를 호출하도록 되어 있습니다. 하지만 우리가 정의한 클래스에는 __str__() 함수가 구현되어 있지 않습니다.

그럼 이 객체가 담고 있는 숫자가 출력이 되도록 클래스에 __str__() 함수를 추가해볼까요?

class NumberHolder:
    def __init__(self, number):
        self.number = number

    def __str__(self):        return f"NumberHolder({self.number})"

다시 인스턴스를 생성하여 print() 함수의 인자로 넘겨보면 원하는 모습으로 출력이 되는 것을 볼 수 있습니다.

print(NumberHolder(1))
NumberHolder(1)

str() 함수 구현에는 f string이 사용되었습니다. 이 부분에 대한 자세한 내용은 관련 포스팅를 참고바랍니다.

여러 개 한 번에 출력

여러 개의 데이터를 한 번에 출력하고 싶을 때도 print() 함수를 유용하게 사용할 수 있습니다. 왜냐하면 print() 함수를 호출 할 때 여러 개의 인자를 한 번에 넘기는 게 가능하기 때문입니다.

예를 들어, 위에서 각각 출력했던 4개의 데이터를 이번에는 한 번에 출력해보겠습니다.

print("안녕", 123, [1, 2.5], {"이름": None, "관리자": True})
안녕 123 [1, 2.5] {'이름': None, '관리자': True}

기본적으로 print() 함수에 여러 인자를 넘기면 출력할 때 각 데이터 사이에 공백 문자를(" ")을 넣어줍니다. 공백 대신에 다른 문자로 데이터를 구분짖고 싶다면 sep 옵션을 사용하면 됩니다.

예를 들어 줄바꿈 문자("\n")를 사용해서 데이터를 구분지어 보겠습니다.

print("안녕", 123, [1, 2.5], {"이름": None, "관리자": True}, sep="\n")
안녕
123
[1, 2.5]
{'이름': None, '관리자': True}

물론 여러 개의 문자로 이뤄진 문자열을 넘길 수도 있습니다.

print("안녕", 123, [1, 2.5], {"이름": None, "관리자": True}, sep=" | ")
안녕 | 123 | [1, 2.5] | {'이름': None, '관리자': True}

한 줄에 출력

print() 함수는 기본적으로 호출할 때 마다 자동으로 줄바꿈을 해주는데요. 종종 이 줄바꿈이 필요가 없을 때가 있습니다.

예를 들어, 다음 4개의 문자열을 print() 함수를 연속해서 호출하면 다음과 같이 4번 줄바꿈이 되지요.

print("어떤 언어를 사용하십니까?")
print("파이썬")
print("자바스크립트")
print("자바")
어떤 언어를 사용하십니까?
자바
파이썬
자바스크립트

만약에 한 줄에 이 모든 문자열을 출력하고 싶다면 어떻게 해야할까요? 바로 end 옵션을 활용해서 줄바꿈 문자("\n") 대신에 사용할 다른 문자열을 명시해주면 됩니다.

print("어떤 언어를 사용하십니까?", end=" ")
print("파이썬", end=", ")
print("자바스크립트", end=", ")
print("자바", end=" 👍\n")
어떤 언어를 사용하십니까? 파이썬, 자바스크립트, 자바 👍

[팁] 2차원 배열 출력

보통 아래와 같이 생긴 2차원 배열을 어떻게 출력하시나요?

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

단순하게 print() 함수의 인자로 넘기면 다음과 같이 한 줄로 출력되어 배열이 크기가 클 경우 보기가 어려워질 수가 있는데요.

print(matrix)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

그래서 시각적으로 알아보기 좋도록 출력하려고 for 문을 사용하여 print() 함수를 반복해서 호출하는 경우가 많이 보게 됩니다.

for row in matrix:
    print(row)
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

하지만 위에서 배운 sep 옵션을 활용하면 다음과 같이 더 간결하게 print() 함수 한 번 호출로 똑같은 효과를 낼 수가 있습니다. 😮

print(*matrix, sep="\n")
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

전체코드

본 포스팅에서 제가 작성한 코드는 아래에서 직접 확인하고 실행해보실 수 있습니다.

https://deepnote.com/project/Blog-Yd3-DsV_QeGqo4AUZ7FyHg/%2Fpython-print.ipynb

마치면서

print() 함수가 워낙 흔하게 사용되다보니 오히려 제대로 학습해볼 기회는 별로 없는 것 같습니다. 이번 기회에 활용법을 잘 숙지하셔서 자주 사용하는 만큼 두고두고 요긴하게 활용하실 수 있으셨으면 좋겠습니다.