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