Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 pprint 모듈 완벽 가이드: 데이터 구조를 예쁘게 출력하는 프리티 프린터

pprint 모듈이란?

pprint 모듈(lib/pprint.py)은 파이썬 표준 라이브러리에 포함되어 있어, 표준 파이썬 배포판과 함께 제공되며 별도의 설치 없이 바로 사용할 수 있습니다. pprint는 'pretty printer(예쁜 출력기)'의 약자로, 파이썬 데이터 구조를 시각적으로 보기 좋은 형태로 출력해 주는 기능을 담당합니다.

파이썬 인터프리터가 올바르게 해석할 수 있는 모든 데이터 구조는 pprint를 통해 깔끔하게 포맷팅됩니다. 포맷된 결과는 가능한 한 한 줄로 유지되지만, 지정된 width(너비) 값을 초과하면 여러 줄로 자동 분할됩니다. 특히 pprint 출력의 독특한 특징 중 하나는 딕셔너리가 화면에 표시되기 전에 키를 기준으로 자동 정렬된다는 점입니다.

PrettyPrinter 클래스 생성자 매개변수

pprint 모듈에는 PrettyPrinter 클래스가 정의되어 있습니다. 생성자는 다음과 같은 형식으로 호출합니다.

pprint.PrettyPrinter(indent, width, depth, stream, compact)
  • indent : 각 재귀 단계마다 추가되는 들여쓰기 양을 지정합니다. 기본값은 1입니다.
  • width : 기본값은 80이며, 출력 폭을 이 값으로 제한합니다. 내용의 길이가 width보다 길면 여러 줄로 나뉩니다.
  • depth : 출력할 계층의 깊이를 제어합니다.
  • stream : 기본값은 sys.stdout(표준 출력 장치)이며, 파일 객체처럼 임의의 스트림 객체를 지정할 수도 있습니다.
  • compact : 기본값은 False입니다. True로 설정하면 width 범위 안에 맞출 수 있는 데이터만 표시됩니다.

PrettyPrinter 클래스의 주요 메서드

  • pprint() : PrettyPrinter 객체의 포맷된 표현(representation)을 출력합니다.
  • pformat() : 생성자에 전달된 매개변수를 기준으로 객체의 포맷된 표현을 문자열로 반환합니다.

기본 사용 예제

다음 예제는 PrettyPrinter 클래스의 간단한 사용법을 보여줍니다.

import pprint

students = {"Dilip": ["English", "Maths", "Science"],
            "Raju": {"English": 50, "Maths": 60, "Science": 70},
            "Kalpana": (50, 60, 70)}

pp = pprint.PrettyPrinter()

print("normal print output")
print(students)
print("----")
print("pprint output")
pp.pprint(students)

실행 결과에서 일반 print() 함수의 출력과 pprint 출력의 차이를 확인할 수 있습니다. pprint는 딕셔너리 키를 알파벳순으로 정렬하고, 각 항목을 여러 줄에 걸쳐 읽기 쉽게 배치합니다.

normal print output
{'Dilip': ['English', 'Maths', 'Science'], 'Raju': {'English': 50, 'Maths': 60, 'Science': 70}, 'Kalpana': (50, 60, 70)}
----
pprint output
{'Dilip': ['English', 'Maths', 'Science'],
'Kalpana': (50, 60, 70),
'Raju': {'English': 50, 'Maths': 60, 'Science': 70}}

편의 함수 pprint()와 pformat()

pprint 모듈은 PrettyPrinter 클래스의 메서드에 대응하는 편의 함수 pprint()와 pformat()도 제공합니다. 아래 예제는 pprint() 함수를 사용한 것입니다.

from pprint import pprint

students = {"Dilip": ["English", "Maths", "Science"],
            "Raju": {"English": 50, "Maths": 60, "Science": 70},
            "Kalpana": (50, 60, 70)}

print("normal print output")
print(students)
print("----")
print("pprint output")
pprint(students)

다음 예제는 pformat() 메서드와 pformat() 함수를 모두 사용합니다. pformat() 메서드를 사용하려면 먼저 PrettyPrinter 객체를 생성해야 하며, 두 경우 모두 포맷된 결과 문자열을 일반 print() 함수로 출력합니다.

import pprint

students = {"Dilip": ["English", "Maths", "Science"],
            "Raju": {"English": 50, "Maths": 60, "Science": 70},
            "Kalpana": (50, 60, 70)}

print("using pformat method")
pp = pprint.PrettyPrinter()
string = pp.pformat(students)
print(string)

print('------')

print("using pformat function")
string = pprint.pformat(students)
print(string)

위 코드의 실행 결과는 다음과 같습니다.

using pformat method
{'Dilip': ['English', 'Maths', 'Science'],
'Kalpana': (50, 60, 70),
'Raju': {'English': 50, 'Maths': 60, 'Science': 70}}
------
using pformat function
{'Dilip': ['English', 'Maths', 'Science'],
'Kalpana': (50, 60, 70),
'Raju': {'English': 50, 'Maths': 60, 'Science': 70}}

사용자 정의 클래스와 함께 사용하기

pprint는 사용자 정의 클래스에도 적용할 수 있습니다. 클래스 내부에서 __repr__() 메서드를 오버라이드하면 됩니다. __repr__() 메서드는 repr() 함수가 호출될 때 실행되며, 파이썬 객체의 공식적인 문자열 표현을 반환합니다. print() 함수에 객체를 인자로 전달하면 repr() 함수의 반환값이 출력됩니다.

다음 예제에서 __repr__() 메서드는 player 객체의 문자열 표현을 반환합니다.

import pprint

class player:
    def __init__(self, name, formats=[], runs=[]):
        self.name = name
        self.formats = formats
        self.runs = runs

    def __repr__(self):
        dct = {}
        dct[self.name] = dict(zip(self.formats, self.runs))
        return (repr(dct))

l1 = ['Tests', 'ODI', 'T20']
l2 = [[140, 45, 39], [15, 122, 36, 67, 100, 49], [78, 44, 12, 0, 23, 75]]
p1 = player("virat", l1, l2)

pp = pprint.PrettyPrinter()
pp.pprint(p1)

위 코드의 실행 결과는 다음과 같습니다.

{'virat': {'Tests': [140, 45, 39], 'ODI': [15, 122, 36, 67, 100, 49], 'T20': [78, 44, 12, 0, 23, 75]}}

재귀 데이터 구조 출력하기

재귀(recursive) 객체를 pprint로 출력하면 첫 번째 표현만 표시되고, 이후 반복되는 재귀 참조에는 해당 객체의 참조 정보만 출력됩니다.

>>> import pprint
>>> numbers = list(range(1, 6))
>>> numbers.append(numbers)
>>> print(numbers)
[1, 2, 3, 4, 5, [...]]
>>> pprint.pprint(numbers)
[1, 2, 3, 4, 5, <Recursion on list with id=1403633698824>]

출력 너비(width) 조절하기

width 매개변수를 기본값인 80에서 다른 값으로 변경하면, 파이썬 문법을 해치지 않는 범위에서 출력이 여러 줄로 나뉘어 표시됩니다.

import pprint

students = {"Dilip": ["English", "Maths", "Science"],
            "Raju": {"English": 50, "Maths": 60, "Science": 70},
            "Kalpana": (50, 60, 70)}

pp = pprint.PrettyPrinter(width=20)
pp.pprint(students)

이 코드는 앞서 살펴본 첫 번째 예제와 동일하지만, PrettyPrinter 객체를 생성할 때 width 매개변수를 20으로 지정했다는 점이 다릅니다. 따라서 pprint 출력이 좁은 폭에 맞춰 다음과 같이 포맷팅됩니다.

{'Dilip': ['English',
           'Maths',
           'Science'],
'Kalpana': (50,
            60,
            70),
'Raju': {'English': 50,
         'Maths': 60,
         'Science': 70}}

마무리

pprint 모듈은 복잡한 데이터 구조를 디버깅하거나 로그로 확인할 때 특히 유용합니다. indent, width, depth 등의 옵션을 적절히 조합하면 중첩된 리스트나 딕셔너리도 한눈에 파악하기 쉬운 형태로 출력할 수 있습니다. 일상적인 개발에서 가독성 높은 출력이 필요하다면 print() 대신 pprint()를 습관적으로 활용해 보시기 바랍니다.