# 8.18. `pprint` — 数据美化输出

源代码： Lib/pprint.py

The `pprint` module provides a capability to “pretty-print” arbitrary Python data structures in a form which can be used as input to the interpreter. If the formatted structures include objects which are not fundamental Python types, the representation may not be loadable. This may be the case if objects such as files, sockets, classes, or instances are included, as well as many other built-in objects which are not representable as Python constants.

格式化后的形式会在可能的情况下以单行来表示对象，并在无法在允许宽度内容纳对象的情况下将其分为多行。 如果你需要调整宽度限制则应显式地构造 `PrettyPrinter` 对象。

在 2.5 版更改: Dictionaries are sorted by key before the display is computed; before 2.5, a dictionary was sorted only if its display required more than one line, although that wasn’t documented.

在 2.6 版更改: Added support for `set` and `frozenset`.

`pprint` 模块定义了一个类：

class `pprint.``PrettyPrinter`(indent=1, width=80, depth=None, stream=None)

  Construct a `PrettyPrinter` instance. This constructor understands several keyword parameters. An output stream may be set using the stream keyword; the only method used on the stream object is the file protocol’s `write()` method. If not specified, the `PrettyPrinter` adopts `sys.stdout`. Three additional parameters may be used to control the formatted representation. The keywords are indent, depth, and width. The amount of indentation added for each recursive level is specified by indent; the default is one. Other values can cause output to look a little odd, but can make nesting easier to spot. The number of levels which may be printed is controlled by depth; 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. The desired output width is constrained using the width parameter; the default is 80 characters. If a structure cannot be formatted within the constrained width, a best effort will be made.

      >>> 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']
      >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
      ... ('parrot', ('fresh fruit',))))))))
      >>> pp = pprint.PrettyPrinter(depth=6)
      >>> pp.pprint(tup)
      ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))

The `PrettyPrinter` class supports several derivative functions:

`pprint.``pformat`(object, indent=1, width=80, depth=None)

  Return the formatted representation of object as a string. indent, width and depth will be passed to the `PrettyPrinter` constructor as formatting parameters.

  在 2.4 版更改: The parameters indent, width and depth were added.

`pprint.``pprint`(object, stream=None, indent=1, width=80, depth=None)

  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 a `print` statement for inspecting values. indent, width and depth will be passed to the `PrettyPrinter` constructor as formatting parameters.

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

  在 2.4 版更改: The parameters indent, width and depth were added.

`pprint.``isreadable`(object)

  Determine if the formatted representation of object is “readable,” or can be used to reconstruct the value using `eval()`. This always returns `False` for recursive objects.

      >>> 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.18.1. PrettyPrinter 对象

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

  返回三个值：字符串形式的 object 已格式化版本，指明结果是否可读的旗标，以及指明是否检测到递归的旗标。 第一个参数是要表示的对象。 第二个是以对象 `id()` 为键的字典，这些对象是当前表示上下文的一部分（影响 object 表示的直接和间接容器）；如果需要呈现一个已经在 context 中表示的对象，则第三个返回值应当为 `True`。 对 `format()` 方法的递归调用应当将容器的附加条目添加到此字典中。 第三个参数 maxlevels 给出了对递归的请求限制；如果没有请求限制则其值将为 `0`。 此参数应当不加修改地传给递归调用。 第四个参数 level 给出于当前层级；传给递归调用的参数值应当小于当前调用的值。

  2.3 新版功能.

## 8.18.2. pprint Example

This example demonstrates several uses of the `pprint()` function and its parameters.

    >>> import pprint
    >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
    ... ('parrot', ('fresh fruit',))))))))
    >>> stuff = ['a' * 10, tup, ['a' * 30, 'b' * 30], ['c' * 20, 'd' * 20]]
    >>> pprint.pprint(stuff)
    ['aaaaaaaaaa',
     ('spam',
      ('eggs',
       ('lumberjack',
        ('knights', ('ni', ('dead', ('parrot', ('fresh fruit',)))))))),
     ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'],
     ['cccccccccccccccccccc', 'dddddddddddddddddddd']]
    >>> pprint.pprint(stuff, depth=3)
    ['aaaaaaaaaa',
     ('spam', ('eggs', (...))),
     ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'],
     ['cccccccccccccccccccc', 'dddddddddddddddddddd']]
    >>> pprint.pprint(stuff, width=60)
    ['aaaaaaaaaa',
     ('spam',
      ('eggs',
       ('lumberjack',
        ('knights',
         ('ni', ('dead', ('parrot', ('fresh fruit',)))))))),
     ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
      'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'],
     ['cccccccccccccccccccc', 'dddddddddddddddddddd']]