> **Источник:** https://python-all.ru/3.3/library/pprint.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 8.11. [`pprint`](https://python-all.ru/3.3/library/pprint.html#module-pprint) – Форматирование данных

**Исходный код:** [Lib/pprint.py](https://python-all.ru/src/3.3/Lib/pprint.py)

---

Модуль [`pprint`](https://python-all.ru/3.3/library/pprint.html#module-pprint) предоставляет возможность «красивого» вывода произвольных структур данных Python в форме, которая может использоваться как входные данные для интерпретатора. Если форматированные структуры содержат объекты, не являющиеся фундаментальными типами Python, представление может быть непригодным для загрузки. Так может быть в случае включения таких объектов, как файлы, сокеты, классы или экземпляры, а также многих других встроенных объектов, которые не представимы в виде констант Python.

Форматированное представление размещает объекты на одной строке, если возможно, и переносит их на несколько строк, если они не помещаются в заданную ширину. Создавайте объекты [`PrettyPrinter`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter) явно, если требуется изменить ограничение по ширине.

Перед выводом словари сортируются по ключам.

Модуль [`pprint`](https://python-all.ru/3.3/library/pprint.html#module-pprint) определяет один класс:

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

Создаёт экземпляр [`PrettyPrinter`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter). Этот конструктор понимает несколько именованных параметров. Выходной поток данных можно задать с помощью ключевого слова *stream*; единственный метод, используемый на объекте потока данных – это метод `write()` из протокола файлов. Если не указано, [`PrettyPrinter`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter) использует `sys.stdout`. Ещё три параметра могут управлять форматированным представлением. Ключевые слова: *indent*, *depth* и *width*. Величина отступа, добавляемого на каждый рекурсивный уровень, задаётся параметром *indent*; по умолчанию – один. Другие значения могут сделать вывод немного необычным, но помогают лучше различать вложенность. Количество уровней, которые могут быть выведены, контролируется параметром *depth*; если выводимая структура данных слишком глубока, следующий вложенный уровень заменяется на `...`. По умолчанию ограничений на глубину форматируемых объектов нет. Желаемая ширина вывода задаётся параметром *width*; по умолчанию 80 символов. Если структуру невозможно отформатировать в заданной ширине, будет предпринята наилучшая попытка.

```python
>>> 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`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter) поддерживает несколько производных функций:

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

Возвращает форматированное представление *object* в виде строки. Параметры *indent*, *width* и *depth* будут переданы конструктору [`PrettyPrinter`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter) в качестве параметров форматирования.

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

Выводит форматированное представление *object* в поток *stream*, за которым следует перевод строки. Если *stream* равен `None`, используется `sys.stdout`. Это может использоваться в интерактивном интерпретаторе вместо функции [`print()`](https://python-all.ru/3.3/library/functions.html#print) для просмотра значений (можно даже переназначить `print = pprint.pprint` для использования в области видимости). Параметры *indent*, *width* и *depth* будут переданы конструктору [`PrettyPrinter`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter) в качестве параметров форматирования.

```python
>>> 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()`](https://python-all.ru/3.3/library/functions.html#eval). Для рекурсивных объектов всегда возвращает `False`.

```python
>>> pprint.isreadable(stuff)
False
```

#### `pprint.isrecursive(object)`

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

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

#### `pprint.saferepr(object)`

Возвращает строковое представление *object*, защищённое от рекурсивных структур данных. Если представление *object* содержит рекурсивную ссылку, она будет представлена как `<Recursion on typename with id=number>`. В остальном представление не форматируется.

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

## 8.11.1. Объекты PrettyPrinter

Экземпляры [`PrettyPrinter`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter) имеют следующие методы:

#### `PrettyPrinter.pformat(object)`

Возвращает отформатированное представление *object*. Учитываются параметры, переданные конструктору [`PrettyPrinter`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter).

#### `PrettyPrinter.pprint(object)`

Выводит отформатированное представление *object* в настроенный поток, после чего добавляет новую строку.

Следующие методы предоставляют реализации соответствующих функций с теми же именами. Использование этих методов на экземпляре немного эффективнее, так как не требуется создавать новые объекты [`PrettyPrinter`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter).

#### `PrettyPrinter.isreadable(object)`

Определяет, является ли отформатированное представление объекта «читаемым» или может быть использовано для восстановления значения с помощью [`eval()`](https://python-all.ru/3.3/library/functions.html#eval). Обратите внимание: для рекурсивных объектов возвращается `False`. Если задан параметр *depth* объекта [`PrettyPrinter`](https://python-all.ru/3.3/library/pprint.html#pprint.PrettyPrinter) и объект глубже допустимого, возвращается `False`.

#### `PrettyPrinter.isrecursive(object)`

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

Этот метод предоставляется как перехватчик (hook), позволяющий подклассам изменять способ преобразования объектов в строки. Реализация по умолчанию использует внутренние механизмы реализации [`saferepr()`](https://python-all.ru/3.3/library/pprint.html#pprint.saferepr).

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

Возвращает три значения: отформатированную версию *object* в виде строки, флаг, указывающий, является ли результат читаемым, и флаг, указывающий, была ли обнаружена рекурсия. Первый аргумент – отображаемый объект. Второй – словарь, который содержит [`id()`](https://python-all.ru/3.3/library/functions.html#id) объектов, являющихся частью текущего контекста представления (прямые и косвенные контейнеры для *object*, влияющие на представление), в качестве ключей; если нужно представить объект, который уже присутствует в *context*, третье возвращаемое значение должно быть `True`. Рекурсивные вызовы метода [`format()`](https://python-all.ru/3.3/library/functions.html#format) должны добавлять дополнительные записи для контейнеров в этот словарь. Третий аргумент, *maxlevels*, задаёт запрошенное ограничение на рекурсию; если ограничения нет, он равен `0`. Этот аргумент следует передавать в рекурсивные вызовы без изменений. Четвёртый аргумент, *level*, задаёт текущий уровень; рекурсивным вызовам следует передавать значение меньше текущего.

## 8.11.2. Пример

Чтобы продемонстрировать несколько вариантов использования функции [`pprint()`](https://python-all.ru/3.3/library/pprint.html#module-pprint) и её параметров, давайте получим информацию о проекте из PyPI:

```python
>>> 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()`](https://python-all.ru/3.3/library/pprint.html#module-pprint) отображает весь объект:

```python
>>> 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* (для более глубокого содержимого используется многоточие):

```python
>>> 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*. Если длинный объект не может быть разбит, указанная ширина будет превышена:

```python
>>> 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"')]
```
