Разработка ПО неизбежно сопряжена с парсингом JSON. Если вы взаимодействуете с API, передаете сообщения между хостами или собираете данные, то, вероятнее всего, используете JSON. Python поставляется со стандартной библиотекой json. Ее возможностей хватает для большинства случаев. Однако некоторые сценарии требуют более гибких и быстрых решений. 

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

1. orjson

Модуль orjson предназначен для работы с большим объемом сложных объектов JSON и молниеносного выполнения операций. Он быстрее стандартной библиотеки Python json и способен обрабатывать множество разных типов данных, включая NumPy.

Главные преимущества этой библиотеки  —  скорость и производительность. Кроме того, она обладает довольно впечатляющими статистическими показателями.

  • Сериализует экземпляры dataclass в 40–50 раз быстрее, чем другие библиотеки.
  • Сериализует экземпляры datetime, date и time в формат RFC 3339, например «1970-01-01T00:00:00+00:00».
  • Сериализует экземпляры numpy.ndarray в 4-12 раз быстрее при 0,3-кратном использовании памяти по сравнению с другими библиотеками.
  • Выводит данные в 10–20 раз быстрее стандартной библиотеки.
  • Сериализует в bytes, а не в str, т.е. не является прямой заменой. 
  • Сериализует str без экранирования Unicode в ASCII, например «好», а не «\\u597d».
  • Сериализует float в 10 раз быстрее, а десериализует в 2 раза быстрее других библиотек.
  • Нативно сериализует подклассы str, int, list и dict, требуя default для указания способов сериализации других типов.
  • Сериализует произвольные типы с помощью хука default.
  • Придерживается строгого соответствия UTF-8, отличается большей точность по сравнению со стандартной библиотекой.
  • Строго соответствует JSON, не поддерживая Nan/Infinity/-Infinity.
  • Соблюдает соответствие JSON в отношении 53-битных целых чисел с предустановленной поддержкой 64-битных.
  • Не предоставляет функции load() и dump() для считывания из/записи в объекты наподобие файлов.

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

2. tortilla

Tortilla  —  настолько потрясающий модуль, что в пору воскликнуть: “Где же ты был всю мою жизнь?!”. Он берет практически любой API и оборачивает его особым образом, позволяя использовать его как обычный набор методов Python. А теперь самое главное преимущество: результаты хранятся как обыкновенные атрибуты, так что к ним можно получить доступ без вынужденных манипуляций с необработанными данными JSON. 

Данный модуль творит чудеса. Если вы раз за разом вручную создавали собственную логику парсинга API на стороне клиента, то пора остановиться, сделать шаг назад и попробовать поработать с этим модулем прямо сейчас. 

Убедитесь на примере, как легко Tortilla взаимодействует с API JSONPlaceholder:

import tortilla

api = tortilla.wrap('https://jsonplaceholder.typicode.com')

todo = api.todos(1).get()

print(todo)>>> {'userId': 1, 'id': 1, 'title': 'delectus aut autem', 'completed': False}

Нужно лишь предоставить модулю Tortilla базовый URL, и он автоматически его обернет. Совсем как настоящая тортилья! 

3. jsonpickle

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

Модуль jsonpickle хранит сериализованные объекты Python в удобном для чтения формате JSON. Вы спокойно их открываете и считываете, не боясь увидеть нечто непонятное.

Например, создадим следующий класс и объект: 

class Foo:
self.bar = 1
foo = Foo()

С помощью jsonpickle этот базовый объект легко сериализуется в JSON: 

import jsonpickle
jsonpickle.dumps(foo)
>>> '{"py/object": "__main__.Foo", "bar": 1}'

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

4. jsondiff

Допустим, вам поступает большой blob-объект JSON, который нужно сравнить с другим вновь полученным blob-объектом и выявить различия между ними. Можно самостоятельно просмотреть содержимое и попытаться найти отличия или воспользоваться более разумным подходом в виде модуля jsondiff.

Данный модуль позволяет быстро найти отличия между двумя разными объектами JSON. Сравним два blob-объекта JSON: 

blob_1 = {'one': 1, 'two': 2, 'three': 3}
blob_2 = {'one': 1, 'two': 22, 'three': 3}

Отличие между ними очевидно, но пусть его найдет модуль jsondiff:

import jsondiff
jsondiff.diff(blob_1, blob_2)
>>> {'two': 22}

А теперь представьте, что такую операцию нужно выполнить применительно к blob-объекту, содержащему тысячи символов и тонны вложенных объектов. Без модуля jsondiff это будет похоже на поиски иголки в стоге сена. Еще одно преимущество данного модуля состоит в том, что он позволяет программно искать различия и перехватывать ошибки API до того, как они попадут в продакшн. 

5. GenSON

При работе с большим количеством данных JSON может потребоваться настройка специального форматирования и типизации для blob-объектов JSON. Одно из решений заключается в создании схемы JSON. С ее помощью вы указываете типы полей, требования и другие атрибуты для общей структуры JSON. 

Модуль GenSON  —  это превосходная библиотека для создания схем JSON в Python. Он позволяет их конструировать с помощью понятного синтаксиса построения. Создадим простую схему: 

from genson import SchemaBuilder

schema_builder = SchemaBuilder()
schema_builder.add_schema({"type": "object", "properties": {}})
schema_builder.add_object({"my_obj": 123})

schema_builder.to_schema()

>>> {'$schema': 'http://json-schema.org/schema#', 'type': 'object', 'properties': {'my_obj': {'type': 'integer'}}, 'required': ['my_obj']}

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

Процесс построения схемы JSON может оказаться довольно сложным. Более подробная информация о типах и требованиях к созданию схем содержится в официальной документации JSON Schema.

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

Читайте нас в TelegramVK и Дзен


Перевод статьи Tate Galbraith: Python Modules That Make Handling JSON Even Faster

Предыдущая статьяСоздание сайдбара с помощью HTML, CSS и JavaScript
Следующая статьяPrefect 2.3.0 добавляет поддержку для потоков, определенных в образах Docker и репозиториях GitHub