8.11. pprint — 数据漂亮打印机 — Python 文档

来自菜鸟教程
Python/docs/3.6/library/pprint
跳转至:导航、​搜索

8.11. 打印 — 数据漂亮的打印机

源代码: :source:`Lib/pprint.py`



pprint 模块提供了一种以可用作解释器输入的形式“漂亮地打印”任意 Python 数据结构的功能。 如果格式化结构包含不是基本 Python 类型的对象,则表示可能无法加载。 如果包含文件、套接字或类等对象,以及许多其他不能表示为 Python 文字的对象,则可能会出现这种情况。

如果可以,格式化表示将对象保留在一行上,如果它们不适合允许的宽度,则将它们分成多行。 如果需要调整宽度约束,请显式构造 PrettyPrinter 对象。

字典在计算显示之前按关键字排序。

pprint 模块定义了一个类:

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

构造一个 PrettyPrinter 实例。 这个构造函数理解几个关键字参数。 可以使用 stream 关键字设置输出流; 流对象上使用的唯一方法是文件协议的 write() 方法。 如果不指定,PrettyPrinter采用sys.stdout。 每个递归级别添加的缩进量由 indent 指定; 默认为一。 其他值可能会导致输出看起来有点奇怪,但可以使嵌套更容易发现。 可打印的层数由depth控制; 如果正在打印的数据结构太深,则下一个包含的级别将替换为 ...。 默认情况下,对正在格式化的对象的深度没有限制。 使用 width 参数限制所需的输出宽度; 默认值为 80 个字符。 如果结构无法在受约束的宽度内格式化,则将尽最大努力。 如果 compact 为 false(默认值),长序列的每一项都将在单独的行上进行格式化。 如果 compact 为真,则将在每个输出行上格式化适合 width 的尽可能多的项目。

3.4 版更改: 添加 compact 参数。

>>> 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 模块还提供了几个快捷功能:

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

object 的格式化表示作为字符串返回。 indentwidthdepthcompact 将作为格式参数传递给 PrettyPrinter 构造函数。

3.4 版更改: 添加 compact 参数。

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

stream 上打印 object 的格式化表示,后跟换行符。 如果 streamNone,则使用 sys.stdout。 这可以在交互式解释器中使用,而不是用于检查值的 print() 函数(您甚至可以重新分配 print = pprint.pprint 以在范围内使用)。 indentwidthdepthcompact 将作为格式参数传递给 PrettyPrinter 构造函数。

3.4 版更改: 添加 compact 参数。

>>> 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)
确定 object 是否需要递归表示。

还定义了另一个支持函数:

pprint.saferepr(object)

返回 object 的字符串表示,防止递归数据结构。 如果 object 的表示公开了递归条目,则递归引用将表示为 <Recursion on typename with id=number>。 该表示没有以其他方式格式化。

>>> pprint.saferepr(stuff)
"[<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']"

8.11.1. PrettyPrinter 对象

PrettyPrinter 实例有以下方法:

PrettyPrinter.pformat(object)
返回 object 的格式化表示。 这考虑了传递给 PrettyPrinter 构造函数的选项。
PrettyPrinter.pprint(object)
在配置的流上打印 object 的格式化表示,后跟换行符。

以下方法提供了对应的同名函数的实现。 由于不需要创建新的 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 给出当前级别; 递归调用应该传递一个小于当前调用的值。


8.11.2. 例子

为了演示 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'}