본문 바로가기
Python Basic

print 문은 어떻게 동작할까?

by mjk0618 2023. 3. 19.

00. print문을 사용한 문자열 출력

파이썬을 처음 배울 때, print문을 사용하여 화면에 원하는 내용을 출력하는 것으로 시작하곤 합니다.

 

그리고 첫 실습으로 다음과 같은 과제를 수행하기도 하죠.

특별히 이런 과제에는 공백에 주의해서 문자열을 정확하게 출력해달라는 조건도 흔히 따라붙습니다.

저는 여기서 +와 ,를 사용하여 문자열을 구분하는 방식을 눈여겨봤습니다.

 


 

01. print문 내부에서 +와 , 의 차이점

먼저 + 를 사용하여 문자열을 연결해서 출력하면 다음과 같이 나옵니다.

그리고 , 를 사용하여 문자열을 출력하면 다음과 같이 나오죠.

여기까지는 누구나 알고 있습니다. 근데 왜냐고 물어보면 어떻게 설명해야 할까요?

보통은 그냥 아 덧셈을 사용하면 공백없이 문자열을 연결해서 출력해주고,

반점을 사용하면 공백을 넣어서 출력하는구나라고 생각하고 넘어갈 것이라고 생각합니다.

 

그런데 저는 그 동작 원리가 어떤지 궁금해서 조금 더 확인해봤습니다.

파이썬에서는 객체가 될텐데, 일반적으로 어떤 대상의 정체를 알아볼 때 먼저 type()함수로 타입체킹을 합니다.

 

우선 첫 번째 코드를 살펴보면 다음과 같이 str 타입이라고 알려줍니다.

그리고 아마 이 문자열의 덧셈은 다음과 같이 str 타입의 __add__ 매직 메서드가 실행되기 때문이겠죠.

그럼 이제 두 번째 코드의 타입을 확인해보겠습니다.

이런 식으로는 확인이 되지 않겠죠. 에러 내용을 보니까 type함수는 인자를 1개 또는 3개만 받는다고 합니다.

인자 1개를 받아서 객체의 타입을 확인해주는 것은 알았는데 3개를 받는다는 내용은 모르는 분들이 많을 것 같습니다.

이는 Subtype(혹은 Sub class)와 연관이 있는데 이에 대해서는 나중에 따로 다루도록 하겠습니다.

 

여튼 코드를 그대로 넣으면 에러가 발생하니 다른 방법을 사용해봤습니다.

그런데 위의 코드는 사실 임의로 두 문자열을 튜플로 패킹하였기 때문에 타입을 확인하는 것도 조금 우습네요.

그러면 살짝 변형을 가해서 아래와 같이 확인해보면 어떨까요?

그래도 여전히 타입은 튜플이고, 튜플을 print문으로 출력하는 건 각 문자열을 콤마로 구분하여 출력하는 것과는 다르네요.

 


 

02. print문의 내부 동작 원리

그러면 파이썬에서 print문은 어떤 방식으로 동작하는지 builtin function의 원형을 찾아보았습니다.

vscode에서 print문의 definition을 따라가보면 builtin.pyi라는 파일에 다음과 같이 적혀있습니다.

여기서 우리가 주목해야 할 부분은 *values 입니다.

함수의 파라미터 앞에 *(asterisk)를 붙이면 가변인자를 받아서 패킹해줍니다.

(이 부분을 잘 모르시는 분들은 파이썬 가변인자에 대해서 검색해서 확인해보시면 될 것 같습니다.)

따라서 print문이 여러 개의 인자를 받는다는 것은 이해했습니다.

 

그러면 출력은 어떻게 될까요?

이 파일에서는 출력이 어떻게 이루어지는지는 자세히 알기 어렵습니다.

 

사실 .pyi 파일은 실제로는 함수의 동작과는 크게 관련이 없습니다.

.pyi는 python interface의 줄임말로, 파이썬의 내부 모듈의 인터페이스를 정의한 파일입니다.

즉, 어떤 입력을 받고 어떤 출력을 내보내는지를 이해하기 쉽게 별도로 정리해둔 파일이라고 생각하시면 됩니다.

 

많은 builtin 함수들의 실제 코드는 속도나 성능을 고려하여 C++로 짜여있기 때문에 파이썬만으로는 알아보기 어렵습니다.

파이썬만을 이용해서 동작원리를 알아보는 게 목표이니, 같은 기능을 하는 파이썬 코드로 살짝 번역해보겠습니다.

코드를 보면 output은 separator를 기준으로 문자열을 join하여 만들어집니다.

print문에 end라는 파라미터가 있다는 사실은 흔히 알고 있지만, sep은 잘 모르시는 분들이 많을 거라 생각합니다.

알고보니 구분자 sep이 공백 하나를 default값으로 갖고 있었고, 이 구분자를 기준으로 문자열이 합쳐지는 것이었네요.

 

print문과 구분하기 위해서 my\_print라고 함수명을 정의하고 실제로 실행해보면, 

기대한 대로 문자열이 공백으로 구분되어 출력되는 것을 확인할 수 있습니다.

 

이렇게 print문이 내부적으로 어떻게 동작하는지 확인했습니다.

정리하자면, 여러 개의 문자열을 가변인자로 입력받아 튜플로 패킹하고,

튜플의 각 문자열을 언패킹하여 구분자를 기준으로 출력해준다고 할 수 있겠습니다.

 

또한, print문 내부에서 +는 단순히 더해진 문자열이 함수의 입력이 된다는 점,

콤마는 가변인자와 관련이 있다는 점에서 동작 원리에 차이가 있다는 것을 알 수 있습니다.


댓글