# `pprint` — 예쁜 데이터 인쇄기

소스 코드: Lib/pprint.py

`pprint` 모듈은 임의의 파이썬 데이터 구조를 인터프리터의 입력으로 사용할 수 있는 형태로 “예쁘게 인쇄”할 수 있는 기능을 제공합니다. 포맷된 구조에 기본 파이썬 형이 아닌 객체가 포함되면, 표현은 로드되지 않을 수 있습니다. 파일, 소켓 또는 클래스와 같은 객체뿐만 아니라 파이썬 리터럴로 표현할 수 없는 다른 많은 객체가 포함된 경우입니다.

포맷된 표현은 할 수 있다면 객체를 한 줄에 유지하고, 허용된 너비에 맞지 않으면 여러 줄로 나눕니다. 너비 제한을 조정해야 하면 `PrettyPrinter` 객체를 명시적으로 만드십시오.

딕셔너리는 디스플레이를 계산하기 전에 키로 정렬됩니다.

버전 3.9에서 변경: `types.SimpleNamespace`를 예쁘게 인쇄하는 지원이 추가되었습니다.

`pprint` 모듈은 하나의 클래스를 정의합니다:

class `pprint.``PrettyPrinter`(indent=1, width=80, depth=None, stream=None, *, compact=False, sort_dicts=True)

  `PrettyPrinter` 인스턴스를 만듭니다. 이 생성자는 여러 키워드 매개 변수를 인식합니다. 출력 스트림은 stream 키워드를 사용하여 설정할 수 있습니다; 스트림 객체에서 사용되는 유일한 메서드는 파일 프로토콜의 `write()` 메서드입니다. 지정하지 않으면, `PrettyPrinter`는 `sys.stdout`을 사용합니다. 각 재귀 수준에 대해 들여쓰기하는 양은 indent로 지정합니다; 기본값은 1입니다. 다른 값은 출력이 약간 이상하게 보일 수 있지만, 중첩을 쉽게 알아낼 수 있습니다. 인쇄될 수 있는 수준의 수는 depth로 제어합니다; 인쇄 중인 데이터 구조가 너무 깊으면, 다음에 포함된 수준은 `...`로 대체됩니다. 기본적으로, 포맷되는 객체의 깊이에는 제한이 없습니다. 원하는 출력 폭은 width 매개 변수를 사용하여 제한합니다; 기본값은 80자입니다. 제한된 너비 내에서 구조를 포맷할 수 없으면, 최선의 노력을 기울입니다. compact가 거짓(기본값)이면, 긴 시퀀스의 각 항목이 별도의 줄로 포맷됩니다. compact가 참이면 width 내에 들어갈 수 있는 최대한 많은 항목을 각 출력할 줄에 포맷합니다. sort_dicts가 참(기본값)이면, 딕셔너리는 키가 정렬되어 포맷합니다, 그렇지 않으면 삽입 순서로 표시됩니다.

  버전 3.4에서 변경: compact 매개 변수가 추가되었습니다.

  버전 3.8에서 변경: sort_dicts 매개 변수가 추가되었습니다.

      >>> import pprint
      >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
      >>> stuff.insert(0, stuff[:])
      >>> pp = pprint.PrettyPrinter(indent=4)
      >>> pp.pprint(stuff)
      [   ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
          'spam',
          'eggs',
          'lumberjack',
          'knights',
          'ni']
      >>> pp = pprint.PrettyPrinter(width=41, compact=True)
      >>> pp.pprint(stuff)
      [['spam', 'eggs', 'lumberjack',
        'knights', 'ni'],
       'spam', 'eggs', 'lumberjack', 'knights',
       'ni']
      >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
      ... ('parrot', ('fresh fruit',))))))))
      >>> pp = pprint.PrettyPrinter(depth=6)
      >>> pp.pprint(tup)
      ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))

`pprint` 모듈은 몇 가지 단축 함수도 제공합니다:

`pprint.``pformat`(object, indent=1, width=80, depth=None, *, compact=False, sort_dicts=True)

  object의 포맷된 표현을 문자열로 반환합니다. indent, width, depth, compact 및 sort_dicts는 포매팅 매개 변수로 `PrettyPrinter` 생성자에 전달됩니다.

  버전 3.4에서 변경: compact 매개 변수가 추가되었습니다.

  버전 3.8에서 변경: sort_dicts 매개 변수가 추가되었습니다.

`pprint.``pp`(object, *args, sort_dicts=False, **kwargs)

  object의 포맷된 표현을 인쇄하고 줄 넘김을 붙입니다. sort_dicts가 거짓(기본값)이면, 딕셔너리는 키가 삽입된 순서대로 표시됩니다, 그렇지 않으면 딕셔너리 키가 정렬됩니다. args와 kwargs는 포매팅 매개 변수로 `pprint()`로 전달됩니다.

  버전 3.8에 추가.

`pprint.``pprint`(object, stream=None, indent=1, width=80, depth=None, *, compact=False, sort_dicts=True)

  object의 포맷된 표현에 줄 바꿈을 추가해서 stream에 인쇄합니다. stream이 `None`이면, `sys.stdout`이 사용됩니다. 이것은 `print()` 함수 대신 대화형 인터프리터에서 값을 검사하는 데 사용할 수 있습니다 (스코프 내에서 사용하기 위해 `print = pprint.pprint`를 다시 대입할 수도 있습니다). indent, width, depth, compact 및 sort_dicts는 포매팅 매개 변수로 `PrettyPrinter` 생성자에 전달됩니다.

  버전 3.4에서 변경: compact 매개 변수가 추가되었습니다.

  버전 3.8에서 변경: sort_dicts 매개 변수가 추가되었습니다.

      >>> import pprint
      >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
      >>> stuff.insert(0, stuff)
      >>> pprint.pprint(stuff)
      [<Recursion on list with id=...>,
       'spam',
       'eggs',
       'lumberjack',
       'knights',
       'ni']

`pprint.``isreadable`(object)

  object의 포맷된 표현이 “읽을 수 있는”지, 즉 `eval()`을 사용하여 값을 재구성하는 데 사용할 수 있는지 판단합니다. 재귀적 객체에 대해서는 항상 `False`를 반환합니다.

      >>> pprint.isreadable(stuff)
      False

`pprint.``isrecursive`(object)

  object가 재귀적 표현을 요구하는지 판단합니다.

또 하나의 지원 함수가 정의됩니다:

`pprint.``saferepr`(object)

  재귀적 데이터 구조에 대해 보호되는, object의 문자열 표현을 반환합니다. object의 표현이 재귀적 항목을 노출하면, 재귀적 참조는 `<Recursion on typename with id=number>`로 표시됩니다. 표현에는 이외의 다른 포매팅이 적용되지 않습니다.

      >>> pprint.saferepr(stuff)
      "[<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']"

## PrettyPrinter 객체

`PrettyPrinter` 인스턴스에는 다음과 같은 메서드가 있습니다:

`PrettyPrinter.``pformat`(object)

  object의 포맷된 표현을 반환합니다. `PrettyPrinter` 생성자에 전달된 옵션을 고려합니다.

`PrettyPrinter.``pprint`(object)

  구성된 스트림에 object의 포맷된 표현과 불 넘김을 인쇄합니다.

다음 메서드는 같은 이름의 해당 함수에 대한 구현을 제공합니다. 새로운 `PrettyPrinter` 객체를 만들 필요가 없으므로, 인스턴스에서 이러한 메서드를 사용하는 것이 약간 더 효율적입니다.

`PrettyPrinter.``isreadable`(object)

  object의 포맷된 표현이 “읽을 수 있는”지, 즉 `eval()`을 사용하여 값을 재구성하는 데 사용할 수 있는지 판단합니다. 재귀 객체에 대해 `False`를 반환함에 유의하십시오. `PrettyPrinter`의 depth 매개 변수가 설정되고 객체가 허용된 것보다 더 깊으면, `False`를 반환합니다.

`PrettyPrinter.``isrecursive`(object)

  object가 재귀적 표현을 요구하는지 판단합니다.

이 메서드는 서브 클래스가 객체가 문자열로 변환되는 방식을 수정할 수 있도록 하는 훅으로 제공됩니다. 기본 구현은 `saferepr()` 구현의 내부를 사용합니다.

`PrettyPrinter.``format`(object, context, maxlevels, level)

  세 가지 값을 반환합니다: 포맷된 버전의 object를 문자열로, 결과가 읽을 수 있는지를 나타내는 플래그와 재귀가 감지되었는지를 나타내는 플래그. 첫 번째 인자는 표시할 객체입니다. 두 번째는 현재 표현 컨텍스트(표현에 영향을 주는 object의 직접 및 간접 컨테이너)의 일부인 객체의 `id()`를 키로 포함하는 딕셔너리입니다; 이미 context에 표현된 객체가 표현되어야 할 필요가 있으면, 세 번째 반환 값은 `True`이어야 합니다. `format()` 메서드에 대한 재귀 호출은 컨테이너에 대한 추가 항목을 이 딕셔너리에 추가해야 합니다. 세 번째 인자 maxlevels는 재귀에 요청된 제한을 줍니다; 요청된 제한이 없으면 `0`입니다. 이 인자는 재귀 호출에 수정되지 않은 채 전달되어야 합니다. 네 번째 인자 level은 현재 수준을 제공합니다; 재귀 호출은 현재 호출보다 작은 값으로 전달되어야 합니다.

## 예제

`pprint()` 함수와 매개 변수의 여러 용도를 예시하기 위해, PyPI에서 프로젝트에 대한 정보를 가져옵시다:

    >>> import json
    >>> import pprint
    >>> from urllib.request import urlopen
    >>> with urlopen('https://pypi.org/pypi/sampleproject/json') as resp:
    ...     project_info = json.load(resp)['info']

기본적인 형태에서, `pprint()`는 전체 객체를 보여줍니다:

    >>> pprint.pprint(project_info)
    {'author': 'The Python Packaging Authority',
     'author_email': 'pypa-dev@googlegroups.com',
     'bugtrack_url': None,
     'classifiers': ['Development Status :: 3 - Alpha',
                     'Intended Audience :: Developers',
                     'License :: OSI Approved :: MIT License',
                     'Programming Language :: Python :: 2',
                     'Programming Language :: Python :: 2.6',
                     'Programming Language :: Python :: 2.7',
                     'Programming Language :: Python :: 3',
                     'Programming Language :: Python :: 3.2',
                     'Programming Language :: Python :: 3.3',
                     'Programming Language :: Python :: 3.4',
                     'Topic :: Software Development :: Build Tools'],
     'description': 'A sample Python project\n'
                    '=======================\n'
                    '\n'
                    'This is the description file for the project.\n'
                    '\n'
                    'The file should use UTF-8 encoding and be written using '
                    'ReStructured Text. It\n'
                    'will be used to generate the project webpage on PyPI, and '
                    'should be written for\n'
                    'that purpose.\n'
                    '\n'
                    'Typical contents for this file would include an overview of '
                    'the project, basic\n'
                    'usage examples, etc. Generally, including the project '
                    'changelog in here is not\n'
                    'a good idea, although a simple "What\'s New" section for the '
                    'most recent version\n'
                    'may be appropriate.',
     'description_content_type': None,
     'docs_url': None,
     'download_url': 'UNKNOWN',
     'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
     'home_page': 'https://github.com/pypa/sampleproject',
     'keywords': 'sample setuptools development',
     'license': 'MIT',
     'maintainer': None,
     'maintainer_email': None,
     'name': 'sampleproject',
     'package_url': 'https://pypi.org/project/sampleproject/',
     'platform': 'UNKNOWN',
     'project_url': 'https://pypi.org/project/sampleproject/',
     'project_urls': {'Download': 'UNKNOWN',
                      'Homepage': 'https://github.com/pypa/sampleproject'},
     'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
     'requires_dist': None,
     'requires_python': None,
     'summary': 'A sample Python project',
     'version': '1.2.0'}

결과는 특정 depth로 제한될 수 있습니다 (더 깊은 내용에는 줄임표가 사용됩니다):

    >>> pprint.pprint(project_info, depth=1)
    {'author': 'The Python Packaging Authority',
     'author_email': 'pypa-dev@googlegroups.com',
     'bugtrack_url': None,
     'classifiers': [...],
     'description': 'A sample Python project\n'
                    '=======================\n'
                    '\n'
                    'This is the description file for the project.\n'
                    '\n'
                    'The file should use UTF-8 encoding and be written using '
                    'ReStructured Text. It\n'
                    'will be used to generate the project webpage on PyPI, and '
                    'should be written for\n'
                    'that purpose.\n'
                    '\n'
                    'Typical contents for this file would include an overview of '
                    'the project, basic\n'
                    'usage examples, etc. Generally, including the project '
                    'changelog in here is not\n'
                    'a good idea, although a simple "What\'s New" section for the '
                    'most recent version\n'
                    'may be appropriate.',
     'description_content_type': None,
     'docs_url': None,
     'download_url': 'UNKNOWN',
     'downloads': {...},
     'home_page': 'https://github.com/pypa/sampleproject',
     'keywords': 'sample setuptools development',
     'license': 'MIT',
     'maintainer': None,
     'maintainer_email': None,
     'name': 'sampleproject',
     'package_url': 'https://pypi.org/project/sampleproject/',
     'platform': 'UNKNOWN',
     'project_url': 'https://pypi.org/project/sampleproject/',
     'project_urls': {...},
     'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
     'requires_dist': None,
     'requires_python': None,
     'summary': 'A sample Python project',
     'version': '1.2.0'}

또한, 최대 문자 width를 제안할 수 있습니다. 긴 객체를 분할 할 수 없으면, 지정된 너비를 초과합니다:

    >>> pprint.pprint(project_info, depth=1, width=60)
    {'author': 'The Python Packaging Authority',
     'author_email': 'pypa-dev@googlegroups.com',
     'bugtrack_url': None,
     'classifiers': [...],
     'description': 'A sample Python project\n'
                    '=======================\n'
                    '\n'
                    'This is the description file for the '
                    'project.\n'
                    '\n'
                    'The file should use UTF-8 encoding and be '
                    'written using ReStructured Text. It\n'
                    'will be used to generate the project '
                    'webpage on PyPI, and should be written '
                    'for\n'
                    'that purpose.\n'
                    '\n'
                    'Typical contents for this file would '
                    'include an overview of the project, '
                    'basic\n'
                    'usage examples, etc. Generally, including '
                    'the project changelog in here is not\n'
                    'a good idea, although a simple "What\'s '
                    'New" section for the most recent version\n'
                    'may be appropriate.',
     'description_content_type': None,
     'docs_url': None,
     'download_url': 'UNKNOWN',
     'downloads': {...},
     'home_page': 'https://github.com/pypa/sampleproject',
     'keywords': 'sample setuptools development',
     'license': 'MIT',
     'maintainer': None,
     'maintainer_email': None,
     'name': 'sampleproject',
     'package_url': 'https://pypi.org/project/sampleproject/',
     'platform': 'UNKNOWN',
     'project_url': 'https://pypi.org/project/sampleproject/',
     'project_urls': {...},
     'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
     'requires_dist': None,
     'requires_python': None,
     'summary': 'A sample Python project',
     'version': '1.2.0'}