pprint --- 數據美化輸出?

源代碼: Lib/pprint.py


pprint 模塊提供了“美化打印”任意 Python 數據結構的功能,這種美化形式可用作對解釋器的輸入。 如果經格式化的結構包含非基本 Python 類型的對象,則其美化形式可能無法被加載。 包含文件、套接字或類對象,以及許多其他不能用 Python 字面值來表示的對象都有可能導致這樣的結果。

格式化后的形式會在可能的情況下以單行來表示對象,并在無法在允許寬度內容納對象的情況下將其分為多行。 如果你需要調整寬度限制則應顯式地構造 PrettyPrinter 對象。

字典在計算其顯示形式前會先根據鍵來排序。

在 3.9 版更改: 添加了對美化打印 types.SimpleNamespace 的支持。

在 3.10 版更改: 添加了對美化打印 dataclasses.dataclass 的支持。

pprint 模塊定義了一個類:

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.

其他值可用來配置復雜數據結構嵌套要以何種形式被展示。

indent (默認為 1) 指定要為每個縮進層級添加的縮進量。

depth 控制可被打印的縮進層級數量;如果要打印的數據結構層級過深,則其所包含的下一層級將用 ... 替換。 默認情況下,對于被格式化對象的層級深度沒有任何限制。

width (默認為 80) 指定輸出中每行所允許的最大字符數。 如果一個數據結構無法在寬度限制之內被格式化,將顯示盡可能多的內容。

compact 影響長序列(列表、元組、集合等等)的格式化方式。 如果 compact 為假值(默認)則序列的每一項將格式化為單獨的行。 如果 compact 為真值,則每個輸出行格式化時將在 width 的限制之內盡可能地容納多個條目。

如果 sort_dicts 為真值(默認),字典在格式化時將基于鍵進行排序,否則它們將按插入順序顯示。

如果 underscore_numbers 為真值,整數在格式化時將使用 _ 字符作為千位分隔符,否則不顯示下劃線(默認)。

在 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', (...)))))))
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 above.

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

打印 object 的格式化表示并附帶一個換行符。 如果 sort_dicts 為假值(默認),字典將按鍵的插入順序顯示,否則將按字典鍵排序。 argskwargs 將作為格式化形參被傳給 pprint()。

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

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

確定 object 的格式化表示是否“可讀”,或是否可被用來通過 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 對象?

PrettyPrinter 的實例具有下列方法:

PrettyPrinter.pformat(object)?

返回 object 格式化表示。 這會將傳給 PrettyPrinter 構造器的選項納入考慮。

PrettyPrinter.pprint(object)?

在所配置的流上打印 object 的格式化表示,并附加一個換行符。

下列方法提供了與同名函數相對應的實現。 在實例上使用這些方法效率會更高一些,因為不需要創(chuàng)建新的 PrettyPrinter 對象。

PrettyPrinter.isreadable(object)?

確定對象的格式化表示是否“可讀”,或者是否可使用 eval() 重建對象值。 請注意此方法對于遞歸對象將返回 False。 如果設置了 PrettyPrinterdepth 形參并且對象深度超出允許范圍,此方法將返回 False。

PrettyPrinter.isrecursive(object)?

確定對象是否需要遞歸表示。

此方法作為一個鉤子提供,允許子類修改將對象轉換為字符串的方式。 默認實現使用 saferepr() 實現的內部方式。

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

返回三個值:字符串形式的 object 已格式化版本,指明結果是否可讀的旗標,以及指明是否檢測到遞歸的旗標。 第一個參數是要表示的對象。 第二個是以對象 id() 為鍵的字典,這些對象是當前表示上下文的一部分(影響 object 表示的直接和間接容器);如果需要呈現一個已經在 context 中表示的對象,則第三個返回值應當為 True。 對 format() 方法的遞歸調用應當將容器的附加條目添加到此字典中。 第三個參數 maxlevels 給出了對遞歸的請求限制;如果沒有請求限制則其值將為 0。 此參數應當不加修改地傳給遞歸調用。 第四個參數 level 給出于當前層級;傳給遞歸調用的參數值應當小于當前調用的值。

示例?

為了演示 pprint() 函數及其形參的幾種用法,讓我們從 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']

pprint() 以其基本形式顯示了整個對象:

>>>
>>> pprint.pprint(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.pprint(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.pprint(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'}