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

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, adjustable by the *width* parameter defaulting to 88
characters.

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

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


関数
====

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

   *object* のフォーマットされた表現を出力して、その後に newline を続
   けます。この関数は、対話型インタプリタの中で値を調査するために
   "print()" 関数の代わりに使用されることがあります。Tips： さらに、ス
   コープ内で使用するために "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*) -- 出力の1行あたり最大文字数を指定します。構
        造が幅の制約の中で整形できない場合、最善の努力がなされます。

      * **depth** (*int** | **None*) -- 表示される入れ子レベルの数を制
        御します。表示されるデータ構造が深すぎる場合、含まれる次のレベ
        ルは``...``で置き換えられます。"None" （デフォルト）の場合、フ
        ォーマットされるオブジェクトの深さに制約はありません。

      * **compact** (*bool*) -- Control the way long *sequences* are
        formatted. If "False" (the default), opening parentheses and
        brackets will be followed by a newline and the following
        content will be indented by one level, similar to pretty-
        printed JSON. If "True", as many items as will fit within the
        *width* will be formatted on each output line.

      * **sort_dicts** (*bool*) -- Trueの場合、辞書は辞書のキー順にソ
        ートされて整形されます。そうでなければ挿入順に表示されます（デ
        フォルト）。

      * **underscore_numbers** (*bool*) -- Trueの場合、整数は``_``で3
        桁区切りされて表示されます。そうでなければアンダースコアは表示
        されません（デフォルト）。

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

   Added in version 3.8.

pprint.pprint(object, stream=None, indent=4, width=88, 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=4, width=88, 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 the
   documentation above.

pprint.isreadable(object)

   *object* を書式化して出力できる("readable") か、あるいは "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)

   Return a string representation of *object*, protected against
   recursion in some common data structures, namely instances of
   "dict", "list" and "tuple" or subclasses whose "__repr__" has not
   been overridden.  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 objects
=====================

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

   Construct a "PrettyPrinter" instance.

   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()
   >>> pp.pprint(stuff)
   [
       ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
       'spam',
       'eggs',
       'lumberjack',
       'knights',
       'ni',
   ]
   >>> pp = pprint.PrettyPrinter(indent=1, width=41, compact=True)
   >>> pp.pprint(stuff)
   [['spam', 'eggs', 'lumberjack',
     'knights', 'ni'],
    'spam', 'eggs', 'lumberjack', 'knights',
    'ni']
   >>> pp = pprint.PrettyPrinter(width=41, indent=3)
   >>> 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".

   バージョン 3.15 で変更: Changed default *indent* from 1 to 4 and
   default *width* from 80 to 88. The default "compact=False" layout
   is now similar to pretty-printed JSON, with opening parentheses and
   brackets followed by a newline and the contents indented by one
   level.

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