pprint --- データ出力の整然化

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


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

可能であればオブジェクトを1行で整形しますが、与えられた幅に合わないなら複数行に分けて整形します。 出力幅を指定したい場合は、 PrettyPrinter オブジェクトを作成して明示してください。

辞書は表示される前にキーの順でソートされます。

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

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

関数

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

object のフォーマットされた表現の後に改行を入れて表示します。もし sort_dicts が false (デフォルト) ならば、辞書はキーが挿入順に表示され、そうでなければ、辞書のキーがソートされます。 argskwargs はフォーマットパラメータとして pprint() に渡されます。

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

stream 上に object のフォーマットされた表現を出力して、その後に newline を続けます。 streamNone の場合、 sys.stdout が使用されます。これは、対話型インタプリタの中で値を調査するために print() 関数の代わりに使用されることがあります (さらに、スコープ内で使用するために print = pprint.pprint を再代入することができます)。

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

This module defines one class:

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

PrettyPrinter のインスタンスを生成します。このコンストラクタにはいくつかのキーワード引数を設定できます。

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 を返すことに注意して下さい。もし PrettyPrinterdepth 引数が設定されていて、オブジェクトのレベルが設定よりも深かったら、 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 で現在のレベルを設定します。再帰呼び出しでは、現在の呼び出しより小さい値が渡されます。

使用例

To demonstrate several uses of the pp() function and its parameters, let's fetch information about a project from 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']

In its basic form, pp() shows the whole object:

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