Шаг 175.
Python: тонкости программирования.
Трюки со словарем. Структурная печать словаря

    На этом шаге мы рассмотрим способы вывода содержимого словаря.

    Вы когда-либо пытались выявить баг в одной из своих программ, усеивая ее кучей отладочных инструкций print, чтобы проследить поток исполнения? Или, возможно, вам приходилось генерировать диагностическое сообщение, чтобы выводить некоторые параметры конфигурации...

    Наверняка вы были разочарован, и часто, тем, насколько трудно в Python читать некоторые структуры данных, когда они печатаются как текстовые строки. Например, ниже приведен простой словарь. Он напечатан в сеансе интерпретатора, при этом порядок следования ключей произвольный и в результирующей строке отсутствует выделение отступами:

>>> mapping = {'a': 23, 'c''c': 42, 'c': 0xc0ffee}
>>> str(mapping)
{'b': 42, 'c': 12648430, 'a': 23}

    К счастью, есть несколько простых в использовании альтернатив неразборчивому преобразованию в стиле to-string, дающих более удобочитаемый результат. Один из вариантов состоит в использовании встроенного модуля Python json. Чтобы выполнить структурную печать словаря с более приятным форматированием, можно применить функцию

<B>json.dumps()</B>:
>>> import json
>>> json.dumps(mapping, indent=4, sort_keys=True)
{
    "a": 23,
    "b": 42,
    "c": 12648430
}

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

    Несмотря на то что это решение дает внешне красивый и удобочитаемый результат, оно не является идеальным. Печать словарей при помощи модуля json работает только со словарями, которые содержат примитивные типы, - вы столкнетесь с проблемой при попытке распечатать словарь, который содержит непримитивный тип данных, таких как функция:

>>> json.dumps({all: 'yup'})
Traceback (most recent call last):
.   .   .   .
TypeError: keys must be str, int, float, bool or None, not builtin_function_or_method

    Еще один недостаток использования функции json.dumps() состоит в том, что она не способна сериализовать составные типы данных, такие как множества:

>>> mapping['d'] = {1, 2, 3}
>>> json.dumps(mapping)
Traceback (most recent call last):
.   .   .   .
TypeError: Object of type set is not JSON serializable

    Кроме того, вы можете столкнуться с такой проблемой, как представление текста в кодировке Юникод, - в некоторых случаях вы не сможете взять результат на выходе из json.dumps() и скопиРовать его в сеансе интерпретатора Python, чтобы реконструировать первоначальный объект-словарь.

    Классическим решением задачи структурной печати объектов Python является встроенный модуль pprint. Приведем пример:

>>> import pprint
>>> pprint.pprint(mapping)
{'a': 23, 'b': 42, 'c': 12648430, 'd': set([1, 2, 3])}

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

    Вместе с тем, по сравнению с json.dumps(), она не представляет вложенные структуры визуально столь же хорошо. В зависимости от обстоятельств это может быть преимуществом или недостатком. Я иногда использую json.dumps(), чтобы выводить словари из-за улучшенной удобочитаемости и форматирования, но только если уверены, что в них нет непримитивных типов данных.

    На следующем шаге мы рассмотрим подитожим изученный материал.




Предыдущий шаг Содержание Следующий шаг