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

**ソースコード:** Lib/pprint.py

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

"pprint" モジュールを使うと、Pythonの任意のデータ構造をインタープリタ
への入力で使われる形式にして "pretty-print" できます。書式化された構造
の中にPythonの基本的なタイプではないオブジェクトがあるなら、表示できな
いかもしれません。表示できないのは、ファイル、ソケット、あるいはクラス
のようなオブジェクトや、 その他Pythonのリテラルとして表現できない様々
なオブジェクトが含まれていた場合です。

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" の pretty-print サポー
トが追加されました。

バージョン 3.10 で変更: "dataclasses.dataclass" の pretty-print サポー
トが追加されました。


関数
====

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* を書式化して出力できる("readable") か、あるいは "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* を書式化して出力できる（"readable"）か、あるいは "eval()"
   を使って値を再構成できるかを返します。これは再帰的なオブジェクトに
   対して "False" を返すことに注意して下さい。もし "PrettyPrinter" の
   *depth* 引数が設定されていて、オブジェクトのレベルが設定よりも深か
   ったら、 "False" を返します。

PrettyPrinter.isrecursive(object)

   オブジェクトが再帰的な表現かどうかを返します。

このメソッドをフックとして、サブクラスがオブジェクトを文字列に変換する
方法を修正するのが可能になっています。デフォルトの実装では、内部で
"saferepr()" を呼び出しています。

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

   次の3つの値を返します。*object* をフォーマット化して文字列にしたも
   の、その結果が読み込み可能かどうかを示すフラグ、再帰が含まれている
   かどうかを示すフラグ。最初の引数は表示するオブジェクトです。 2つめ
   の引数はオブジェクトの "id()" をキーとして含むディクショナリで、オ
   ブジェクトを含んでいる現在の（直接、間接に *object* のコンテナとし
   て表示に影響を与える）環境です。ディクショナリ *context* の中でどの
   オブジェクトが表示されたか表示する必要があるなら、3つめの返り値は
   "True" になります。 "format()" メソッドの再帰呼び出しではこのディク
   ショナリのコンテナに対してさらにエントリを加えます。 3つめの引数
   *maxlevels* で再帰呼び出しのレベルを制限します。制限しない場合、
   "0" になります。この引数は再帰呼び出しでそのまま渡されます。 4つめ
   の引数 *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'}
