pprint — Приятная печать данных

Исходный код: Lib/pprint.py


Модуль pprint предоставляет возможность «красиво распечатать» произвольные структуры данных Python в форме, которая может использоваться в качестве входных данных для интерпретатора. Если форматированные структуры включают объекты, которые не являются фундаментальными типами Python, представление может быть не загружаемым. Это может иметь место, если включены такие объекты, как файлы, сокеты или классы, а также многие другие объекты, которые не могут быть представлены как литералы Python.

Форматированное представление хранит объекты в одной строке, если это возможно, и разбивает их на несколько строк, если они не помещаются в допустимую ширину. Создавайте объекты PrettyPrinter явно, если вам нужно настроить ограничение ширины.

Словари сортируются по ключу перед вычислением отображения.

Модуль pprint определяет один класс:

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

Создать экземпляр PrettyPrinter. Этот конструктор понимает несколько ключевый параметров. Выходной поток может быть установлен с использованием ключевого stream; единственный метод, используемый для объекта потока — это метод write() файлового протокола. Если не указано иное, PrettyPrinter принимает sys.stdout. Величина отступа, добавляемого для каждого рекурсивного уровня, определяется indent; по умолчанию — один. Другие значения могут сделать вывод немного странным, но могут упростить обнаружение вложенности. Количество уровней, которые могут быть напечатаны, контролируется depth; если печатаемая структура данных слишком глубокая, следующий содержащийся уровень заменяется на .... По умолчанию нет ограничений на глубину форматируемых объектов. Требуемая ширина вывода ограничивается параметром width; по умолчанию — 80 символов. Если структура не может быть отформатирована в пределах ограниченной ширины, будут приложены все усилия. Если у compact значение ложь (по умолчанию), каждый элемент длинной последовательности будет отформатирован в отдельной строке. Если compact истинно, столько элементов, сколько поместится в width, будет отформатировано в каждой строке вывода. Если sort_dicts — истина (по умолчанию), словари будут отформатированы с отсортированными ключами, в противном случае они будут отображаться в порядке вставки.

Изменено в версии 3.4: Добавлен параметр compact.

Изменено в версии 3.8: Добавлен параметр sort_dicts.

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

Возвращает форматированное представление object в виде строки. indent, width, depth, compact и sort_dicts будут переданы в конструктор PrettyPrinter в качестве параметров форматирования.

Изменено в версии 3.4: Добавлен параметр compact.

Изменено в версии 3.8: Добавлен параметр sort_dicts.

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

Печатает форматированное представление object, за которым следует новая строка. Если sort_dicts имеет ложное значение (по умолчанию), словари будут отображаться с их ключами в порядке вставки, в противном случае ключи dict будут отсортированы. args и kwargs будут переданы в pprint() в качестве параметров форматирования.

Добавлено в версии 3.8.

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

Печатает форматированное представление object на stream, за которым следует новая строка. Если streamNone, используется sys.stdout. Может использоваться в интерактивном интерпретаторе вместо функции print() для проверки значений (вы даже можете переназначить print = pprint.pprint для использования в пределах области действия). indent, width, depth, compact и sort_dicts будут переданы в конструктор PrettyPrinter в качестве параметров форматирования.

Изменено в версии 3.4: Добавлен параметр compact.

Изменено в версии 3.8: Добавлен параметр sort_dicts.

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

Объекты PrettyPrinter

Экземпляры PrettyPrinter имеют следующие методы:

PrettyPrinter.pformat(object)

Возвращает форматированное представление object. При этом учитываются параметры, переданные конструктору PrettyPrinter.

PrettyPrinter.pprint(object)

Распечатать отформатированное представление object в настроенном потоке с последующей новой строкой.

Следующие методы предоставляют реализации для соответствующих одноименных функций. Использование этих методов в экземпляре немного более эффективно, поскольку новые объекты PrettyPrinter создавать не нужно.

PrettyPrinter.isreadable(object)

Определить, является ли форматированное представление объекта «читаемым» или его можно использовать для восстановления значения с помощью eval(). Обратите внимание, что он возвращает False для рекурсивных объектов. Если параметр depth в PrettyPrinter установлен и объект глубже, чем разрешено, возвращается 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'}