Содержание страницы
8.11. pprint – Форматирование данных¶pprint – Data pretty printer
Исходный код: Lib/pprint.py
Модуль pprint предоставляет возможность «красивого» вывода произвольных структур данных Python в форме, которая может использоваться как входные данные для интерпретатора. Если форматированные структуры содержат объекты, не являющиеся фундаментальными типами Python, представление может быть непригодным для загрузки. Так может быть в случае включения таких объектов, как файлы, сокеты, классы или экземпляры, а также многих других встроенных объектов, которые не представимы в виде констант Python.
Форматированное представление размещает объекты на одной строке, если возможно, и переносит их на несколько строк, если они не помещаются в заданную ширину. Создавайте объекты PrettyPrinter явно, если требуется изменить ограничение по ширине.
Перед выводом словари сортируются по ключам.
Модуль pprint определяет один класс:
- class pprint.PrettyPrinter(indent=1, width=80, depth=None, stream=None)¶
Создаёт экземпляр PrettyPrinter. Этот конструктор понимает несколько именованных параметров. Выходной поток данных можно задать с помощью ключевого слова stream; единственный метод, используемый на объекте потока данных – это метод write() из протокола файлов. Если не указано, PrettyPrinter использует sys.stdout. Ещё три параметра могут управлять форматированным представлением. Ключевые слова: indent, depth и width. Величина отступа, добавляемого на каждый рекурсивный уровень, задаётся параметром indent; по умолчанию – один. Другие значения могут сделать вывод немного необычным, но помогают лучше различать вложенность. Количество уровней, которые могут быть выведены, контролируется параметром depth; если выводимая структура данных слишком глубока, следующий вложенный уровень заменяется на .... По умолчанию ограничений на глубину форматируемых объектов нет. Желаемая ширина вывода задаётся параметром width; по умолчанию 80 символов. Если структуру невозможно отформатировать в заданной ширине, будет предпринята наилучшая попытка.
>>> 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', (...)))))))
Класс PrettyPrinter поддерживает несколько производных функций:
- pprint.pformat(object, indent=1, width=80, depth=None)¶
Возвращает форматированное представление object в виде строки. Параметры indent, width и depth будут переданы конструктору PrettyPrinter в качестве параметров форматирования.
- pprint.pprint(object, stream=None, indent=1, width=80, depth=None)¶
Выводит форматированное представление object в поток stream, за которым следует перевод строки. Если stream равен None, используется sys.stdout. Это может использоваться в интерактивном интерпретаторе вместо функции print() для просмотра значений (можно даже переназначить print = pprint.pprint для использования в области видимости). Параметры indent, width и depth будут переданы конструктору PrettyPrinter в качестве параметров форматирования.
>>> 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 «читаемым» (readable) или может быть использовано для восстановления значения с помощью 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 Objects
Экземпляры PrettyPrinter имеют следующие методы:
- PrettyPrinter.pformat(object)¶
Возвращает отформатированное представление object. Учитываются параметры, переданные конструктору PrettyPrinter.
- PrettyPrinter.pprint(object)¶
Выводит отформатированное представление object в настроенный поток, после чего добавляет новую строку.
Следующие методы предоставляют реализации соответствующих функций с теми же именами. Использование этих методов на экземпляре немного эффективнее, так как не требуется создавать новые объекты PrettyPrinter.
- PrettyPrinter.isreadable(object)¶
Определяет, является ли отформатированное представление объекта «читаемым» или может быть использовано для восстановления значения с помощью eval(). Обратите внимание: для рекурсивных объектов возвращается False. Если задан параметр depth объекта PrettyPrinter и объект глубже допустимого, возвращается False.
- PrettyPrinter.isrecursive(object)¶
Определяет, требует ли объект рекурсивного представления.
Этот метод предоставляется как перехватчик (hook), позволяющий подклассам изменять способ преобразования объектов в строки. Реализация по умолчанию использует внутренние механизмы реализации saferepr().
- PrettyPrinter.format(object, context, maxlevels, level)¶
Возвращает три значения: отформатированную версию object в виде строки, флаг, указывающий, является ли результат читаемым, и флаг, указывающий, была ли обнаружена рекурсия. Первый аргумент – отображаемый объект. Второй – словарь, который содержит id() объектов, являющихся частью текущего контекста представления (прямые и косвенные контейнеры для object, влияющие на представление), в качестве ключей; если нужно представить объект, который уже присутствует в context, третье возвращаемое значение должно быть True. Рекурсивные вызовы метода format() должны добавлять дополнительные записи для контейнеров в этот словарь. Третий аргумент, maxlevels, задаёт запрошенное ограничение на рекурсию; если ограничения нет, он равен 0. Этот аргумент следует передавать в рекурсивные вызовы без изменений. Четвёртый аргумент, level, задаёт текущий уровень; рекурсивным вызовам следует передавать значение меньше текущего.
8.11.2. Пример¶Example
Чтобы продемонстрировать несколько вариантов использования функции pprint() и её параметров, давайте получим информацию о проекте из PyPI:
>>> import json
>>> import pprint
>>> from urllib.request import urlopen
>>> with urlopen('http://pypi.python.org/pypi/configparser/json') as url:
... http_info = url.info()
... raw_data = url.read().decode(http_info.get_content_charset())
>>> project_info = json.loads(raw_data)
>>> result = {'headers': http_info.items(), 'body': project_info}
В базовом виде pprint() отображает весь объект:
>>> pprint.pprint(result)
{'body': {'info': {'_pypi_hidden': False,
'_pypi_ordering': 12,
'classifiers': ['Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Topic :: Software Development :: Libraries',
'Topic :: Software Development :: Libraries :: Python Modules'],
'download_url': 'UNKNOWN',
'home_page': 'http://docs.python.org/py3k/library/configparser.html',
'keywords': 'configparser ini parsing conf cfg configuration file',
'license': 'MIT',
'name': 'configparser',
'package_url': 'http://pypi.python.org/pypi/configparser',
'platform': 'any',
'release_url': 'http://pypi.python.org/pypi/configparser/3.2.0r3',
'requires_python': None,
'stable_version': None,
'summary': 'This library brings the updated configparser from Python 3.2+ to Python 2.6-2.7.',
'version': '3.2.0r3'},
'urls': [{'comment_text': '',
'downloads': 47,
'filename': 'configparser-3.2.0r3.tar.gz',
'has_sig': False,
'md5_digest': '8500fd87c61ac0de328fc996fce69b96',
'packagetype': 'sdist',
'python_version': 'source',
'size': 32281,
'upload_time': '2011-05-10T16:28:50',
'url': 'http://pypi.python.org/packages/source/c/configparser/configparser-3.2.0r3.tar.gz'}]},
'headers': [('Date', 'Sat, 14 May 2011 12:48:52 GMT'),
('Server', 'Apache/2.2.16 (Debian)'),
('Content-Disposition', 'inline'),
('Connection', 'close'),
('Transfer-Encoding', 'chunked'),
('Content-Type', 'application/json; charset="UTF-8"')]}
Результат можно ограничить определённой depth (для более глубокого содержимого используется многоточие):
>>> pprint.pprint(result, depth=3)
{'body': {'info': {'_pypi_hidden': False,
'_pypi_ordering': 12,
'classifiers': [...],
'download_url': 'UNKNOWN',
'home_page': 'http://docs.python.org/py3k/library/configparser.html',
'keywords': 'configparser ini parsing conf cfg configuration file',
'license': 'MIT',
'name': 'configparser',
'package_url': 'http://pypi.python.org/pypi/configparser',
'platform': 'any',
'release_url': 'http://pypi.python.org/pypi/configparser/3.2.0r3',
'requires_python': None,
'stable_version': None,
'summary': 'This library brings the updated configparser from Python 3.2+ to Python 2.6-2.7.',
'version': '3.2.0r3'},
'urls': [{...}]},
'headers': [('Date', 'Sat, 14 May 2011 12:48:52 GMT'),
('Server', 'Apache/2.2.16 (Debian)'),
('Content-Disposition', 'inline'),
('Connection', 'close'),
('Transfer-Encoding', 'chunked'),
('Content-Type', 'application/json; charset="UTF-8"')]}
Кроме того, можно задать максимальную width. Если длинный объект не может быть разбит, указанная ширина будет превышена:
>>> pprint.pprint(result['headers'], width=30)
[('Date',
'Sat, 14 May 2011 12:48:52 GMT'),
('Server',
'Apache/2.2.16 (Debian)'),
('Content-Disposition',
'inline'),
('Connection', 'close'),
('Transfer-Encoding',
'chunked'),
('Content-Type',
'application/json; charset="UTF-8"')]