Добро пожаловать, коллеги-энтузиасты Python! Сегодня мы погрузимся в удобный инструмент, который облегчит вам жизнь кодера: pprint, сокращение от "pretty-print". К концу этой статьи вы станете профессионалом в pprint, зная, когда и как использовать его, чтобы сделать ваши данные более читаемыми и управляемыми. Итак, начнем! Если совсем коротко: pprint это модуль стандартной библиотеки, который печатает вложенные словари и списки не одной длинной строкой, а с переносами и отступами. Устанавливать ничего не нужно: пишем from pprint import pprint и дальше вызываем pprint(data) вместо print(data).

Кратко

  • pprint входит в стандартную библиотеку: ставить ничего не надо, достаточно from pprint import pprint.
  • Модуль разбивает структуру на строки по ширине (по умолчанию 80 символов) и выравнивает вложенность отступами.
  • Ключи словарей pprint по умолчанию сортирует по алфавиту, поэтому порядок в выводе может отличаться от порядка в коде.
  • Поведение настраивается параметрами width, indent, depth, compact и sort_dicts.
  • С Python 3.8 есть короткая функция pp(), которая ключи не сортирует, и параметр sort_dicts=False у обычного pprint().
  • Для JSON-совместимых данных ту же задачу решает json.dumps(data, indent=2), но он умеет далеко не все объекты Python.

Что такое pprint в Python?

Вы когда-нибудь смотрели на беспорядочную мешанину вложенных словарей или списков и думали: "Должен быть лучший способ прочитать это"? Если да, то pprint здесь, чтобы спасти вас. Модуль pprint в Python разработан для предоставления более понятного человеку вывода для сложных структур данных, таких как словари, списки и их вложенные комбинации.

Проще говоря, pprint форматирует ваши данные аккуратно и понятно, делая их гораздо более понятными с первого взгляда. Это как волшебная палочка, которая превращает ваши хаотичные данные в хорошо организованный, читаемый формат. Давайте подробнее разберемся, почему это так полезно.

Почему вывод с помощью обычной функции print() иногда непрактичен

Хотя обычная функция print() отлично подходит для простых данных, она может стать кошмаром при работе со сложными структурами. Представьте, что у вас есть вложенный словарь с несколькими слоями. Печать его с помощью print() приведет к однострочному выводу, который практически невозможно прочитать. Например:

data = {'name': 'Alice', 'age': 30, 'children': [{'name': 'Bob', 'age': 10}, {'name': 'Charlie', 'age': 8}]}
print(data)

Это выведет:

{'name': 'Alice', 'age': 30, 'children': [{'name': 'Bob', 'age': 10}, {'name': 'Charlie', 'age': 8}]}

Все в одной строке! Трудно различить, что находится внутри каждого словаря или списка. Вот где pprint сияет. Он форматирует вывод более структурированным и удобочитаемым образом.

Создание словаря Pretty Print

Давайте посмотрим, как pprint может преобразовать предыдущий пример в нечто гораздо более удобоваримое. Сначала вам нужно импортировать pprint из модуля pprint:

from pprint import pprint

data = {'name': 'Alice', 'age': 30, 'children': [{'name': 'Bob', 'age': 10}, {'name': 'Charlie', 'age': 8}]}
pprint(data)

И вывод будет таким:

{'age': 30,
 'children': [{'age': 10, 'name': 'Bob'}, {'age': 8, 'name': 'Charlie'}],
 'name': 'Alice'}

Теперь, разве это не намного легче читать? Каждая вложенная структура четко разделена, что упрощает отслеживание иерархии данных.

Обратите внимание на порядок ключей: в коде словарь начинался с name, а в выводе первым идет age. Так и задумано, pprint по умолчанию сортирует ключи по алфавиту. Если порядок важен, с Python 3.8 его сохраняет параметр sort_dicts=False или короткая функция pp() из того же модуля, у которой сортировка отключена изначально.

Преимущества использования pprint

Использование pprint дает несколько преимуществ, особенно при работе с более сложными структурами данных. Вот некоторые основные преимущества:

  • Читаемость: как мы уже видели, pprint упрощает чтение структур данных, разбивая их на более управляемые фрагменты.
  • Отладка: при отладке понятный и организованный вывод помогает вам понять текущее состояние ваших данных, что упрощает обнаружение проблем.
  • Документация: если вам нужно представить структуры данных в документации или журналах, pprint предоставляет понятный и профессиональный формат.
  • Настройка: вы можете настроить формат вывода в соответствии со своими потребностями, используя различные параметры.

Настройка вывода pprint

Модуль pprint это не просто о красивом выводе. Он также позволяет настраивать под свои нужды. Вы можете настроить ширину, глубину и отступ выводимого на печать текста.

  • Ширина: контролирует максимальное количество символов в строке.
  • Глубина: ограничивает количество отображаемых уровней вложенности.
  • Отступ: регулирует уровень отступа.
  • Компактность: параметр compact=True плотнее упаковывает элементы последовательностей, укладывая в строку столько, сколько поместится.

Вот пример:

from pprint import pprint

data = {'name': 'Alice', 'age': 30, 'children': [{'name': 'Bob', 'age': 10}, {'name': 'Charlie', 'age': 8}]}
pprint(data, width=40, indent=2, depth=2)

Вот что получится:

{ 'age': 30,
  'children': [{...}, {...}],
  'name': 'Alice'}

Строки уложились в 40 символов, отступ стал двухпробельным, а вот на вторую строку стоит посмотреть внимательно: вложенные словари превратились в {...}. Так и работает depth: он не показывает структуру до указанного уровня подробнее, а обрезает ее и ставит многоточие. Отрегулируйте эти параметры, чтобы получить идеальный формат для ваших нужд.

А вот как выглядит compact=True на длинном списке:

from pprint import pprint

numbers = list(range(1, 21))
pprint(numbers, width=40, compact=True)

Результат:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
 13, 14, 15, 16, 17, 18, 19, 20]

Без compact=True тот же список занял бы двадцать строк, по одному числу в каждой.

Как получить строку вместо печати: pformat()

Иногда отформатированный вывод нужен не на экране, а в переменной: записать в файл, отправить в лог, вложить в сообщение об ошибке. Для этого в том же модуле есть pformat(): он форматирует точно так же, как pprint(), но не печатает, а возвращает готовую строку.

import logging
from pprint import pformat

data = {'name': 'Alice', 'age': 30, 'children': [{'name': 'Bob', 'age': 10}, {'name': 'Charlie', 'age': 8}]}

logging.basicConfig(level=logging.DEBUG, format='%(levelname)s: %(message)s')
logging.debug('Состояние данных:\n%s', pformat(data, width=40))

В логе появится аккуратная многострочная запись:

DEBUG: Состояние данных:
{'age': 30,
 'children': [{'age': 10,
               'name': 'Bob'},
              {'age': 8,
               'name': 'Charlie'}],
 'name': 'Alice'}

Ограничения и альтернативы

Хотя pprint невероятно полезен, у него есть некоторые ограничения. Это не всегда лучший выбор для очень больших структур данных, так как он все равно может выдавать много выходных данных. Кроме того, если вам нужно отформатировать данные для HTML или других определенных форматов, вам может понадобиться более специализированный инструмент.

Альтернативы pprint

  • Модуль JSON: Для данных JSON модуль json Python также может выполнять красивую печать с помощью json.dumps().
  • Модуль YAML: Для данных YAML модуль pyyaml предлагает читаемый формат.
  • Сторонние библиотеки: Такие библиотеки, как tabulate, могут помочь отформатировать данные в таблицы, которые могут быть более читаемыми для определенных наборов данных.

Ниже сведены все варианты сразу:

Инструмент Что дает Когда брать
print() печатает как есть, одной строкой простые значения и короткие структуры
pprint() из модуля pprint переносы по ширине, отступы, сортировка ключей любые объекты Python: словари, списки, множества, свои классы
json.dumps(data, indent=2) отступы и строгий синтаксис JSON с двойными кавычками данные, которые потом уйдут в файл или в API
yaml.dump() из PyYAML формат YAML, самый компактный для чтения конфиги; библиотека внешняя, ставится отдельно
tabulate таблица со столбцами и разделителями однородные табличные данные; библиотека тоже внешняя

Вот краткий обзор того, как можно использовать модуль json для красивой печати:

import json

data = {'name': 'Alice', 'age': 30, 'children': [{'name': 'Bob', 'age': 10}, {'name': 'Charlie', 'age': 8}]}
print(json.dumps(data, indent=2))

Это выведет:

{
  "name": "Alice",
  "age": 30,
  "children": [
    {
      "name": "Bob",
      "age": 10
    },
    {
      "name": "Charlie",
      "age": 8
    }
  ]
}

Резюме и заключение

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

Мы рассмотрели:

  • Что такое pprint и почему он полезен.
  • Как использовать pprint с примерами.
  • Настройка вывода pprint.
  • Преимущества использования pprint.
  • Некоторые ограничения и альтернативы для красивого вывода данных.

Продолжайте экспериментировать с pprint и другими инструментами форматирования, чтобы найти лучший способ представления ваших данных. Помните, что четкий вывод данных это не только эстетика, это важная часть понимания и поддержки вашего кода. Приятного кодирования!

Дополнительные ресурсы

Не стесняйтесь погружаться в эти ресурсы для более глубокого понимания и более продвинутых методов. Вы так быстро все схватываете, продолжайте в том же духе, и скоро вы станете мастером представления данных в Python!

Вопросы и ответы

Что такое pprint в Python и чем он отличается от print?

Это модуль стандартной библиотеки для «красивой» печати. print() выводит структуру как есть, одной строкой, а pprint() смотрит на ширину строки (по умолчанию 80 символов) и, если объект не помещается, разбивает его на строки с отступами по уровням вложенности. На простых значениях разницы нет, она появляется на вложенных словарях и списках.

Почему pprint переставил ключи словаря?

Потому что по умолчанию он сортирует ключи по алфавиту: так вывод одинаковых по смыслу словарей выглядит одинаково, что удобно при сравнении. Начиная с Python 3.8 сортировку отключает параметр sort_dicts=False, а функция pp() из того же модуля не сортирует ключи изначально.

Как задать ширину строки, отступ и глубину вывода?

Через параметры: pprint(data, width=40, indent=2, depth=2). width это максимальная длина строки, indent это размер отступа для вложенных уровней, а depth ограничивает глубину: все, что лежит ниже указанного уровня, заменяется многоточием в скобках, например {...}. Есть еще compact=True, который плотнее упаковывает элементы последовательностей.

Как получить отформатированную строку вместо печати в консоль?

Функцией pformat() из того же модуля: она возвращает готовую строку, которую можно положить в переменную, записать в файл или передать в логгер, например logging.debug(pformat(data)). Это тот же самый форматировщик, только без вывода на экран.

Когда лучше json.dumps, а когда pprint?

json.dumps(data, indent=2) берут, когда результат должен быть настоящим JSON: уйти в файл, в API или в другой язык. Но он умеет только JSON-совместимые типы: на множестве он упадет с ошибкой «Object of type set is not JSON serializable», а кортеж превратит в массив. pprint же печатает любой объект Python и нужен для чтения глазами и отладки, но его вывод это не JSON, а синтаксис Python.

Работает ли pprint с собственными классами?

Да, но выводит он то, что возвращает метод __repr__ объекта. У обычного класса это малополезная строка вида <__main__.User object at 0x000001>, поэтому __repr__ стоит определить самому. У классов с декоратором @dataclass он генерируется автоматически, а с Python 3.10 pprint умеет и красиво разбивать такие объекты по строкам.

Читайте также: