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 (по умолчанию sys.stdout) - это file-like object, в который будет записан вывод путем вызова его метода write().

Другие значения настраивают способ отображения вложенности сложных структур данных.

indent (по умолчанию 1) задает количество отступов, добавляемых для каждого уровня вложенности.

depth контролирует количество уровней вложенности, которые могут быть выведены на печать; если выводимая структура данных слишком глубока, следующий содержащийся уровень заменяется на .... По умолчанию глубина форматируемых объектов не ограничена.

width (по умолчанию 80) задает желаемое максимальное количество символов в строке вывода. Если структура не может быть отформатирована в пределах ограничения ширины, будет предпринята попытка.

compact влияет на способ форматирования длинных последовательностей (списков, кортежей, множеств и т.д.). Если compact равно false (по умолчанию), то каждый элемент последовательности будет отформатирован на отдельной строке. Если compact равно true, то на каждой выходной строке будет отформатировано столько элементов, сколько поместится в ширину.

Если sort_dicts равно true (по умолчанию), словари будут отформатированы с отсортированными ключами, в противном случае они будут отображаться в порядке вставки.

Если underscore_numbers равно true, целые числа будут отформатированы с символом _ для разделителя тысяч, иначе подчеркивания не будут отображаться (по умолчанию).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Определите, является ли форматированное представление объекта «читаемым» или может быть использовано для восстановления значения с помощью eval(). Для рекурсивных объектов всегда возвращается False.

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

Определите, требует ли объект рекурсивного представления.

Также определена еще одна вспомогательная функция:

pprint.saferepr(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)

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

PrettyPrinter.pprint(object)

Печать форматированного представления объекта в сконфигурированном потоке, за которым следует новая строка.

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

PrettyPrinter.isreadable(object)

Определите, является ли форматированное представление объекта «читаемым» или может быть использовано для восстановления значения с помощью eval(). Обратите внимание, что это возвращает False для рекурсивных объектов. Если параметр depth в PrettyPrinter установлен и объект находится глубже, чем разрешено, возвращается False.

PrettyPrinter.isrecursive(object)

Определите, требует ли объект рекурсивного представления.

Этот метод предоставляется в качестве крючка, чтобы позволить подклассам изменять способ преобразования объектов в строки. Реализация по умолчанию использует внутренние функции реализации saferepr().

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

Возвращает три значения: отформатированную версию объекта в виде строки, флаг, указывающий, доступен ли результат для чтения, и флаг, указывающий, была ли обнаружена рекурсия. Первый аргумент - это объект, который должен быть представлен. Второй - словарь, содержащий в качестве ключей id() объектов, являющихся частью текущего контекста представления (прямые и косвенные контейнеры для объекта, влияющие на представление); если необходимо представить объект, который уже представлен в контексте, то третье возвращаемое значение должно быть 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'}

Результат может быть ограничен определенной глубиной (многоточие используется для более глубокого содержания):

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

Дополнительно может быть предложена максимальная ширина символа ширина. Если длинный объект не может быть разделен, указанная ширина будет превышена:

>>> 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'}
Вернуться на верх