Найти в Дзене
Машинное обучение

Модуль Pickles в Python.

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

Во многих языках программирования есть встроенные инструменты для сериализации. Например, в Java есть java.io.Serializeable, в Ruby — Marshal, а в Python есть pickle. Смотрите, как просто этим инструментом сериализовать почти любой питонский объект: 

 

import pickle

original = [1, 2, 3]

with open('myfile.pickle', 'wb') as outfile:

  pickle.dump(original, outfile)

with open('myfile.pickle', 'rb') as infile:

  identical = pickle.load(infile)

print(original == identical) # True

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

Как это работает? Идея в том, что pickle содержит информацию о том, как реконструировать объект.#Если мы попробуем запринтить строку, которую формирует pickle после сериализации списка выше, то увидим две вещи: ссылку на объявление класса, какое-то количество нечитаемых символов, и значения полей. Приблизительно это читается интерпретатором как “возьми вот этот класс и положи в него значения 1, 2, 3”. 

Обратите внимание, что мы сохраняем состояние объекта, а не объявление. То есть, мы знаем содержимое полей этого класса, но остаемся в неведении относительно его структуры. Это важно для пользовательских типов, потому что в программе, в которой мы собираемся распаковывать pickle, этот класс должен быть объявлен. Иначе мы не сможем его распаковать -- непонятно, какой именно объект инициализировать этими данными. 

За простоту использования pickle полюбили в data science. Оказалось удобно сохранять промежуточные результаты вычислений в полях класса, чтобы к расчетам можно было вернуться позже, без необходимости обучать модель заново. 

Но у pickle есть несколько минусов. 

1. Piсkle -- это питонский формат сериализации и пиклы не годятся для передачи объектов не то что между разными языками, а и иногда даже разными версиями интерпретатора Python. Поэтому если в вашей архитектуре есть модули, которые написаны не на Python, то, может быть, pickle для обмена данными -- не лучший выбор. 

2. Pickle не человеко-читаемы. У pickle есть несколько серий протокола, ранние старались делать такими, чтобы их можно было читать глазами, поздние уже нет, но это все равно мало что изменило: если потом захочется поисследовать данные с помощью cat/head/grep и других полезных утилит bash, то вас будет ждать разочарование. Чтобы прочитать pickle с файловой системы, понадобится Python скрипт -- и это не очень удобно. 

3. Pickle не слишком быстрые, по крайней мере, проигрывают модулю json в скорости. 

4. И последнее: pickle небезопасны. Первое, что написано в документации к модулю -- это предупреждение: 

 

Warning The pickle module is not secure. Only unpickle data you trust.

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

В общем, pickle это питонский формат для сериализации данных. Он удобен, когда нужно на скорую руку сохранить состояние объекта. Pickle хорошо использовать в случаях, когда думаете, что файл не проживет долго и когда нет фокуса на вопросах безопасности. Зная все это, там, где можно, я все же выбираю JSON: это быстрее, это читаемее, это безопаснее. Правда, кода нужно писать чуть больше🐠

Пример кода:

Вывод:

mkarpathak-Inspiron-3542:~/Documents/Python-Programs$ python P60_PickleModule.py
Omkar => {'age': 21,  'name': 'Omkar Pathak',  'key': 'Omkar',  'pay': 40000}
Jagdish => {'age': 50,  'name': 'Jagdish Pathak',  'key': 'Jagdish',  'pay': 50000}

PS: в посте пара ссылок на доку и статьи, пооткрывайте, если есть минутка.

Python/ django
Машинное обучение RU