Продвинутый курс разработки на Python
Глава
>
Уровень

Модули сериализации
Модули Marshal и Pickle

Цель

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

Продолжая идти по тропе, мы находим несколько станций, контролирующих распределение воды и качество почвы на земле, подготавливаемой для будущего урожая. Для обработки данных эффективно использовать сериализацию. Хотя использование JSON может быть эффективным в качестве универсального решения, существуют также несколько специфичных для Python методов сериализации: это модули Marshal и Pickle. Модуль Marshal предназначен для быстрой сериализации/десериализации путём преобразования данных в бинарный формат, что идеально подходит для простых передач данных. Модуль Pickle работает медленнее, но предназначен для обработки более сложных структур данных и гораздо гибче, что делает его идеальным для крупных или приоритетных структур данных.

Чтобы использовать модули Marshal и Pickle, импортируйте их, написав: import marshal и import pickle. Для наших целей мы будем использовать следующие функции:

  • marshal.dumps(): сериализует данные в бинарный формат, предназначен для скорости внутри Python. Принимает один аргумент — данные, которые вы хотите сериализовать; ограничен базовыми типами данных.
  • marshal.loads(): десериализует бинарные данные в читаемые Python типы данных, ограничен в возможностях, но выполняется быстро. Принимает один аргумент — данные, которые нужно десериализовать.
  • pickle.DEFAULT_PROTOCOL: показывает, какая версия протокола по умолчанию используется для сериализации Pickle в вашей версии Python. Протоколы влияют на способ сериализации данных.
  • pickle.HIGHEST_PROTOCOL: показывает, какая версия протокола является самой высокой доступной в вашей версии Python. Протоколы влияют на способ сериализации данных.
  • pickle.dumps(): сериализует сложные структуры Python в бинарном формате в соответствии с используемым протоколом. Принимает два аргумента: данные для сериализации и версию протокола.
  • pickle.loads(): десериализует бинарные данные в читаемые Python типы, обладает широкими возможностями для объектов Python. Принимает один аргумент — данные для десериализации.

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

Чтобы начать, подойдите к светлой метке X внутри небольшой станции мониторинга и встаньте лицом к терминалу компьютера. Станция контролирует давление воды и состояние почвы на близлежащей территории, которая готовится к посадке культур. Существует константа reading, содержащая данные Python, собранные станцией.

Создайте переменную с именем data и сохраните в ней результат вызова функции marshal.dumps() с reading в качестве аргумента. Вот так: data = marshal.dumps(reading). Используйте переменную data с предопределённой функцией display(), чтобы просмотреть сериализованные данные.

Выйдите из станции и направляйтесь к золотой метке X, используйте функцию open(), чтобы открыть дверь и попасть в офис. Подойдите к светлой метке X перед терминалом и выполните десериализацию только что сериализованных данных. Создайте переменную output и сохраните в ней результат marshal.loads() с предыдущей переменной data в качестве аргумента. Используйте функцию write() и передайте output в качестве аргумента, чтобы получить доступ к собранным данным станции мониторинга.

Перейдите к светлой метке X на синем ковре в офисе, на терминале мы проверим протоколы, чтобы определить, какой тип сериализации будет использовать модуль pickle при обработке данных. В предопределённой функции write() установите аргументы pickle.DEFAULT_PROTOCOL и pickle.HIGHEST_PROTOCOL. Это позволит проверить текущий и последний доступный протоколы сериализации.

Переместитесь к тёмной метке X на синем ковре: теперь, когда мы подтвердили протоколы, мы можем проверить хранящиеся данные. Данные собирались и сохранялись на протяжении нескольких месяцев и хранятся в константе samples. Создайте три переменные: sereal_0, sereal_2 и sereal_5 — мы будем использовать их для проверки трёх доступных протоколов сериализации. Протокол 0 — это читаемый ASCII, не очень эффективный; протокол 2 — более эффективный бинарный формат; протокол 5 — последний, с самыми сложными дополнительными возможностями.

Мы сохраним результат вызова pickle.dumps() и передадим ему в аргументы константу samples и соответствующий протокол по номеру в имени переменной. Например, для sereal_0 укажем protocol=0: sereal_0 = pickle.dumps(samples, protocol=0). Используйте sereal_0, sereal_2 и sereal_5 с предопределённой функцией display(), чтобы увидеть различия сериализации для каждого протокола.

Подойдите к светлой метке X на красном ковре и встаньте лицом к терминалу, перезапишите переменную output и сохраните в ней результат pickle.loads(), указав sereal_5 в качестве аргумента, чтобы десериализовать накопленные образцы данных. Используйте функцию display() и оберните output в pformat(), чтобы отобразить данные. Например: await player.display(pformat(output)). Обратите внимание на оценки за каждый месяц, отображённые в терминале, чтобы позже построить график.

Перейдите к тёмной метке X на красном ковре и встаньте у стола, в предопределённой функции write() добавьте оценки, которые вы записали для каждого месяца и которые ранее выводились в терминале. Добавьте их в виде строк в кавычках "" в правильном порядке, как указано в функции, чтобы завершить уровень.

Книга Кода