# `pprint` --- データの整形表示

ソースコード: 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, adjustable by the width parameter defaulting to 80 characters.

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

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

## 関数

pprint.pp(object, stream=None, indent=1, width=80, 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), 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) -- Trueの場合、辞書は辞書のキー順にソートされて整形されます。そうでなければ挿入順に表示されます（デフォルト）。

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

      >>> 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)

  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 オブジェクト

class pprint.PrettyPrinter(indent=1, width=80, 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(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 を書式化して出力できる（"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'}