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

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


pprint モジュールは、任意の Python データ構造を、インタープリタへの入力に使える形式で「整形表示」する機能を提供します。 整形するデータ構造に Python の基本的な型以外のオブジェクトが含まれていると、その表現を読み込めない場合があります。 例えば、ファイル、ソケット、クラスなど、Python のリテラルで表せないオブジェクトが含まれる場合が該当します。

整形された表現では、可能な限りオブジェクトを一行に収め、指定した幅に収まらない場合は複数行に分割します。 幅は width 引数で調整でき、デフォルトは 80 文字です。

バージョン 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, expand=False, sort_dicts=False, underscore_numbers=False)

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

パラメータ:
  • object -- 表示するオブジェクトです。

  • stream (file-like object | None) -- write() メソッドを呼び出して出力を書き込む、ファイルライクオブジェクトです。 None (デフォルト) の場合は sys.stdout を使います。

  • indent (int) -- 入れ子レベルごとに追加されるインデントの量を指定します。

  • width (int) -- 出力の1行あたり最大文字数を指定します。構造が幅の制約の中で整形できない場合、最善の努力がなされます。

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

  • compact (bool) -- 長い シーケンス の整形方法を制御します。 False (デフォルト) の場合、シーケンスの各要素を別々の行に整形します。 そうでなければ、各出力行に width の範囲内でできるだけ多くの要素を並べます。 expand とは併用できません。

  • expand (bool) -- True の場合、開き括弧の後に改行を入れ、続く内容を一段深くインデントします。 整形表示した JSON と似た形式になります。 compact とは併用できません。

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

バージョン 3.10 で変更: underscore_numbers 引数が追加されました。

バージョン 3.11 で変更: sys.stdout が None の場合、書き込みを試みなくなりました。

バージョン 3.15 で変更: expand 引数が追加されました。

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

pp() の別名ですが、sort_dicts のデフォルト値が True になっているため、辞書のキーを自動的にソートします。 必要に応じて、この値がデフォルトで False の pp() を使ってください。

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

object を整形した表現を文字列として返します。 indent、width、depth、compact、expand、sort_dicts、underscore_numbers は、整形用の引数として PrettyPrinter コンストラクターに渡されます。 それぞれの意味は上記の説明と同じです。

pprint.isreadable(object)

オブジェクトの整形された表現が「読み込み可能」、つまり eval() で元の値を再構成できるかどうかを返します。 再帰的なオブジェクトに対しては常に False を返します。

>>> pprint.isreadable(stuff)
False
pprint.isrecursive(object)

object の表現に再帰が必要かどうかを判定します。 この関数には、下記の saferepr() と同じ制限があり、再帰的なオブジェクトを検出できなかった場合は RecursionError を送出することがあります。

pprint.saferepr(object)

一般的なデータ構造で再帰を防ぎながら、object の文字列表現を返します。 対応するのは、dict、list、tuple のインスタンス、または __repr__ をオーバーライドしていないそれらのサブクラスのインスタンスです。 オブジェクトの表現に再帰的な項目が現れる場合、その参照は <Recursion on typename with id=number> と表されます。 それ以外の整形は行いません。

>>> 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, expand=False, sort_dicts=True, underscore_numbers=False)

PrettyPrinter インスタンスを作成します。

引数の意味は pp() と同じです。 ただし、順序が異なり、sort_dicts のデフォルト値は 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']
>>> pp = pprint.PrettyPrinter(width=41, expand=True, 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 で変更: sys.stdout が None の場合、書き込みを試みなくなりました。

バージョン 3.15 で変更: expand 引数が追加されました。

PrettyPrinter インスタンスには以下のメソッドがあります:

PrettyPrinter.pformat(object)

object の書式化した表現を返します。これは PrettyPrinter のコンストラクタに渡されたオプションを考慮して書式化されます。

PrettyPrinter.pprint(object)

object の書式化した表現を指定したストリームに出力し、最後に改行します。

以下のメソッドは、対応する同じ名前の関数と同じ機能を持っています。以下のメソッドをインスタンスに対して使うと、新たに PrettyPrinter オブジェクトを作る必要がないのでちょっぴり効果的です。

PrettyPrinter.isreadable(object)

オブジェクトの整形された表現が「読み込み可能」、つまり 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'}

最後に、expand 引数を使うと、整形表示した JSON のような形式にできます。 indent を大きめの値にすると、より見やすくなります。

>>> pprint.pp(project_info, indent=4, expand=True)
{
   '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},
   'dynamic': None,
   'home_page': 'https://github.com/pypa/sampleproject',
   'keywords': 'sample setuptools development',
   'license': 'MIT',
   'license_expression': None,
   'license_files': None,
   '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',
   },
   'provides_extra': None,
   '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',
   'yanked': False,
   'yanked_reason': None,
}