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

소스 코드: Lib/pprint.py

The `pprint` module provides a capability to “pretty-print” arbitrary Python data structures in a form which can be used as input to the interpreter. If the formatted structures include objects which are not fundamental Python types, the representation may not be loadable. This may be the case if objects such as files, sockets or classes are included, as well as many other objects which are not representable as Python literals.

포맷된 표현은 할 수 있다면 객체를 한 줄에 유지하고, 허용된 너비에 맞지 않으면 여러 줄로 나눕니다. 허용된 너비는 width 매개 변수로 조정할 수 있고, 기본 값은 80 자 입니다.

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

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

## 함수

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

  object의 포맷된 표현에 줄 바꿈을 추가해서 인쇄합니다. 이 함수는 `print()` 함수 대신 대화형 인터프리터에서 값을 검사하는 데 사용할 수 있습니다. 팁: 스코프 내에서 사용하기 위해 `print = pprint.pp`를 다시 대입할 수도 있습니다.

  매개변수:

    - object – The object to be printed.

    - stream (file-like object | None) – A file-like object to which the output will be written by calling its `write()` method. If `None` (the default), `sys.stdout` is used.

    - indent (int) – 각 중첩 수준에 대해 추가되는 들여쓰기 양.

    - width (int) – The desired maximum number of characters per line in the output. If a structure cannot be formatted within the width constraint, a best effort will be made.

    - depth (int | None) – The number of nesting levels which may be printed. If the data structure being printed is too deep, the next contained level is replaced by `...`. If `None` (the default), there is no constraint on the depth of the objects being formatted.

    - compact (bool) – Control the way long sequences are formatted. If `False` (the default), each item of a sequence will be formatted on a separate line, otherwise as many items as will fit within the width will be formatted on each output line.

    - sort_dicts (bool) – If `True`, dictionaries will be formatted with their keys sorted, otherwise they will be displayed in insertion order (the default).

    - underscore_numbers (bool) – If `True`, integers will be formatted with the `_` character for a thousands separator, otherwise underscores are not displayed (the default).

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

  Added in version 3.8.

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

  Alias for `pp()` with sort_dicts set to `True` by default, which would automatically sort the dictionaries’ keys, you might want to use `pp()` instead where it is `False` by default.

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

  object의 포맷된 표현을 문자열로 반환합니다. indent, width, depth, compact, sort_dicts 및 underscore_numbers는 포매팅 매개 변수로 `PrettyPrinter` 생성자에 전달되고, 그 의미는 위 설명서에서 기술된 대입니다.

pprint.isreadable(object)

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

      >>> pprint.isreadable(stuff)
      False

pprint.isrecursive(object)

  Determine if object requires a recursive representation. This function is subject to the same limitations as noted in `saferepr()` below and may raise an `RecursionError` if it fails to detect a recursive object.

pprint.saferepr(object)

  일부 일반적인 자료 구조(`dict`, `list`, `tuple` 과 `__repr__`이 재정의되지 않은 서브클래스의 인스턴스)에서의 재귀에 대해 보호되는, object의 문자열 표현을 반환합니다. 객체의 표현이 재귀적 항목을 노출하면, 재귀적 참조는 `<Recursion on typename with id=number>`로 표시됩니다. 표현에는 이외의 다른 포매팅이 적용되지 않습니다.

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

## PrettyPrinter 객체

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

  `PrettyPrinter` 인스턴스를 만듭니다.

  Arguments have the same meaning as for `pp()`. Note that they are in a different order, and that sort_dicts defaults to `True`.

      >>> 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', (...)))))))

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

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

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

  버전 3.11에서 변경: No longer attempts to write to `sys.stdout` if it is `None`.

`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은 현재 수준을 제공합니다; 재귀 호출은 현재 호출보다 작은 값으로 전달되어야 합니다.

## 예제

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

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

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

    >>> pprint.pp(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.pp(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.pp(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'}