"pprint" --- Data pretty printer
********************************

**소스 코드:** Lib/pprint.py

======================================================================

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

The formatted representation keeps objects on a single line if it can,
and breaks them onto multiple lines if they don't fit within the
allowed width. Construct "PrettyPrinter" objects explicitly if you
need to adjust the width constraint.

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

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

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


함수
====

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

   Prints the formatted representation of *object* followed by a
   newline. If *sort_dicts* is false (the default), dictionaries will
   be displayed with their keys in insertion order, otherwise the dict
   keys will be sorted. *args* and *kwargs* will be passed to
   "pprint()" as formatting parameters.

   >>> 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']

   버전 3.8에 추가.

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

   Prints the formatted representation of *object* on *stream*,
   followed by a newline.  If *stream* is "None", "sys.stdout" is
   used. This may be used in the interactive interpreter instead of
   the "print()" function for inspecting values (you can even reassign
   "print = pprint.pprint" for use within a scope).

   The configuration parameters *stream*, *indent*, *width*, *depth*,
   *compact*, *sort_dicts* and *underscore_numbers* are passed to the
   "PrettyPrinter" constructor and their meanings are as described in
   its documentation below.

   Note that *sort_dicts* is "True" by default and 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)

   Return the formatted representation of *object* as a string.
   *indent*, *width*, *depth*, *compact*, *sort_dicts* and
   *underscore_numbers* are passed to the "PrettyPrinter" constructor
   as formatting parameters and their meanings are as described in its
   documentation below.

pprint.isreadable(object)

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

   >>> pprint.isreadable(stuff)
   False

pprint.isrecursive(object)

   Determine if *object* requires a recursive representation.

pprint.saferepr(object)

   Return a string representation of *object*, protected against
   recursive data structures.  If the representation of *object*
   exposes a recursive entry, the recursive reference will be
   represented as "<Recursion on typename with id=number>".  The
   representation is not otherwise formatted.

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


PrettyPrinter 객체
==================

This module defines one class:

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

   Construct a "PrettyPrinter" instance.  This constructor understands
   several keyword parameters.

   *stream* (default "sys.stdout") is a *file-like object* to which
   the output will be written by calling its "write()" method. If both
   *stream* and "sys.stdout" are "None", then "pprint()" silently
   returns.

   Other values configure the manner in which nesting of complex data
   structures is displayed.

   *indent* (default 1) specifies the amount of indentation added for
   each nesting level.

   *depth* controls 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 "...".  By default, there is no constraint on
   the depth of the objects being formatted.

   *width* (default 80) specifies 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.

   *compact* impacts the way that long sequences (lists, tuples, sets,
   etc) are formatted. If *compact* is false (the default) then each
   item of a sequence will be formatted on a separate line.  If
   *compact* is true, as many items as will fit within the *width*
   will be formatted on each output line.

   If *sort_dicts* is true (the default), dictionaries will be
   formatted with their keys sorted, otherwise they will display in
   insertion order.

   If *underscore_numbers* is true, integers will be formatted with
   the "_" character for a thousands separator, otherwise underscores
   are not displayed (the default).

   버전 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".

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

"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/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'}
