Python — это эксперимент того, сколько свободы нужно программистам. Слишком много свободы и никто не может прочитать чужой код; слишком мало, и выразительность находится под угрозой.
- Гвидо ван Россум
Pickling — это один из модулей Python, который помогает нам в процессах сериализации и десериализации.
В этом посте мы подробно поговорим об этом модуле и взглянем на некоторые другие связанные модули.
Что такое сериализация?
Сериализация — это процесс преобразования данных в линейный формат, который может быть передан некоторым другим экземплярам (коду) или даже другому компьютеру через сеть.
Например, вам может понадобиться сохранить состояние кода (значение объектов после выполнения), как мы это делаем в видеоиграх. Таким образом, вы можете возобновить выполнение кода с того экземпляра, на котором вы остановились.
Поскольку мы сейчас говорим на «Python», мы увидим это на примере кода для облегчения понимания.
class test(): t_int = 10 t_list = [ 1, 2, ‘hello’] t_object = test()
Выше приведен простой код с классом test с двумя членами. С помощью модуля pickle мы можем преобразовать эти структуры объектов (в python типы данных обрабатываются как объекты) в линейный поток данных в байтовом формате.
import pickle class test(): t_int = 10 t_list = [ 1, 2, ‘hello’] t_object = test() pickle_string = pickle.dumps(t_object) print(pickle_string)
При выполнении приведенного выше кода вы можете увидеть двоичные данные, как показано ниже:
b’\x80\x04\x95\x18\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x04test\x94\x93\x94)\x81\x94
По сути, это то, что делает модуль травления. С этим потоком преобразованных данных мы можем передавать их по сети или использовать для сохранения экземпляров объектов. Варианты использования ограничены только потребностями кодирования. Теперь давайте покопаемся в этом модуле.
Официальная документация — нажмите здесь.
В python мы можем выполнить процесс сериализации несколькими способами. Есть три основных модуля, которые помогают нам выполнять сериализацию.
1. Маршал
2. Рассол
3. JSON
Модуль рассола:
Pickle предоставляет 4 метода сериализации и десериализации.
- рассол.dump()
- рассол.dumps()
- рассол.загрузить()
- pickle.loads()
Выделение, сериализация или выравнивание:
С помощью травления мы преобразуем сложные объектные структуры нашего кода либо в файл, либо в строку. pickle.dump() сохраняет входной объект в файл (двоичный формат). Для этого нам нужно создать и открыть файл в формате ‘wb’ (записать в двоичном формате), как указано ниже,
with open(“\usr\bin\code_state”, “wb”) as state: pickle.dump(object, state)
Принимая во внимание, что pickle.dumps() возвращает строку, которую можно легко просмотреть с помощью команды print.
Параметры сериализации:
pickle.dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)
Object : указывает сериализуемый объект.
файл : обозначает файл, в который необходимо записать сериализованные данные.
протокол: в модуле pickle теперь поддерживается шесть версий протокола.
Версия протокола влияет на способ сериализации, а также на совместимость с версией Python.
- Версия 0: самая младшая версия. Вывод в удобочитаемом формате.
- Версия 1: совместима со старыми версиями Python. Вывод в двоичном формате.
- Версия 2: появилась в Python версии 2.3.
- Версия 3: добавлена в Python 3.0. Это версия протокола pickle по умолчанию для версий Python 3.0–3.7. Кроме того, сериализация, выполненная с помощью этого протокола, не может быть десериализована версиями Python 2.x.
- Версия 4:введена в Python 3.4. Расширенная поддержка более широкого диапазона типов объектов для травления. Версия по умолчанию из Python 3.8.
- Версия 5: добавлена в Python 3.8. Добавлена поддержка внеполосных данных и повышена скорость внутриполосных данных.
Импорт исправлений: если для импорта исправлений установлено значение True, а версия протокола меньше 3, pickle попытается сопоставить имена импорта со старыми именами модулей Python 2.x. Так что маринованные данные могут быть распакованы и для версий Python 2.x.
buffer_callback: по умолчанию False. Это введено с Python 3.8 и используется, когда необходимо передать огромные сериализованные данные.
"pickle.dumps()" не имеет файлового параметра, так как возвращает строку.
Можно мариновать следующие виды:
- Нет, Истина и Ложь;
- целые числа, числа с плавающей запятой, комплексные числа
- строки, байты, байтовые массивы
- кортежи, списки, наборы и словари, содержащие только выбираемые объекты
- функции (встроенные и определяемые пользователем), определенные на верхнем уровне модуля (используя определение, а не лямбда)
- классы, определенные на верхнем уровне модуля
Обратите внимание, что некоторые функции Python не могут быть выбраны. Например, если в вашем коде есть "лямбда-функция", то прямая попытка рассола вызовет исключение.
Обойти это можно с помощью функций ‘__getstate__’ и ‘__setstate__’. Мы должны вручную удалить атрибуты, которые нельзя замариновать.
Другим обходным решением может быть использование сторонних модулей, таких как «укроп», для расширения возможностей травления.
Несмотря на то, что с этими дополнительными обходными путями не все поля Python могут быть обработаны. Такие вещи, как программы, связанные с сетевым подключением или подключением к базе данных, не могут быть маринованы, поскольку они намного сложнее.
Распаковка или десериализация:
Распаковку маринованных объектов можно легко выполнить с помощью 'pickle.load()', чтобы распаковать файл, или с помощью 'pickle.loads()', чтобы распаковать выделенную строку. .
Необязательные параметры в Unpickling:
Параметры распаковки в основном определяют, как распаковывать данные, сгенерированные из Python 2.x.
Если fix_imports равно true, pickle попытается сопоставить старые имена Python 2 с новыми именами, используемыми в Python 3.
кодировка и ошибки сообщают pickle, как декодировать экземпляры 8-битных строк, обработанные Python 2; по умолчанию это «ASCII» и «строгий» соответственно. Кодировка может быть «байтами», чтобы читать эти экземпляры 8-битных строк как объекты байтов. Использование encoding=’latin1’ требуется для распаковки массивов NumPy и экземпляров datetime, даты и времени, обработанных Python 2.
Это основные особенности модуля pickle. Теперь давайте вкратце рассмотрим другие варианты сериализации.
Маршал
import marshall
Это старый/древний пакет. Мы можем использовать это и с нашей последней версией Python. Но делать это не рекомендуется из-за отсутствия обратной совместимости и того факта, что он используется интерпретатором для декодирования файлов «.pyc» .
JSON
import json
JSON — это широко известный формат, а модуль python обеспечивает независимую от платформы форму сериализации и десериализации. Кроме того, мы можем сделать это и с файлами формата XML. Одно из основных отличий заключается в том, что JSON является удобочитаемым форматом. Также по сравнению с модулем pickle JSON немного медленнее.
На что следует обратить внимание:
При использовании модуля Pickle существует множество открытых циклов, которые могут сильно повлиять. На его официальной странице также упоминается не десериализовать данные из неизвестных источников. Это потенциально может сломать вашу систему или открыть дверь для взлома.
На всякий случай, если вам нужна безопасность ваших сериализованных данных, мы можем включить использование модуля hmac. Это предотвращает нежелательное вмешательство в обработанные данные.
Кроме того, использование модулей архивирования в некоторой степени уменьшает размер маринованных данных.
Несмотря на это, категорически не рекомендуется извлекать данные из неизвестного источника.
С этим кратким обзором, мы приходим к выводу. Мы увидели, как сериализовать и десериализовать объекты Python, альтернативные модули для них и проблемы, связанные с этим модулем.
Надеюсь, информация, которую я собрала и передала в этом посте, окажется полезной!
Если у вас есть какие-либо вопросы, оставьте комментарий ниже. Удачного изучения Python!!!