Сериализация Python - почему рассол?

87

Я понял, что травление Python - это способ «сохранить» объект Python таким образом, чтобы уважать объектное программирование - в отличие от вывода, записанного в текстовом файле или БД.

У вас есть дополнительные сведения или ссылки по следующим вопросам:

  • где «хранятся» маринованные предметы?
  • почему травление с сохранением представления объекта больше, чем, скажем, хранение в БД?
  • Могу ли я получить маринованные объекты из одного сеанса оболочки Python в другой?
  • у вас есть важные примеры, когда сериализация полезна?
  • подразумевает ли сериализация с помощью pickle «сжатие» данных?

Другими словами, я ищу документ о травлении - Python.doc объясняет, как реализовать рассол, но, похоже, не углубляется в подробности использования и необходимости сериализации.

кирилов
источник
Я предполагаю сохранить состояние для последующего восстановления или поделиться / скопировать объект в другую среду выполнения Python.
синтезаторпатель
13
На многие из ваших вопросов отвечает статья Википедии о сериализации: en.wikipedia.org/wiki/Serialization
NPE
5
Вы спрашиваете, зачем мне нужен Pickle для сериализации в Python? или, скорее, какова (цель) сериализации в конце концов? .
moooeeeep
Может быть, стоит упомянуть о проблемах безопасности с рассолом. Примеры можно найти в документации и в многочисленных вопросах SO, таких как этот .
djvg

Ответы:

99

Обработка - это способ преобразовать объект Python (список, словарь и т. Д.) В поток символов. Идея состоит в том, что этот символьный поток содержит всю информацию, необходимую для восстановления объекта в другом скрипте Python.

Что касается того, где хранится маринованная информация, обычно можно сделать:

with open('filename', 'wb') as f:
    var = {1 : 'a' , 2 : 'b'}
    pickle.dump(var, f)

Это сохранит маринованную версию нашего vardict в файле 'filename'. Затем в другом сценарии вы можете загрузить из этого файла в переменную, и словарь будет воссоздан:

with open('filename','rb') as f:
    var = pickle.load(f)

Другой вариант использования травления - это если вам нужно передать этот словарь по сети (возможно, с помощью сокетов или чего-то еще). Сначала вам нужно преобразовать его в поток символов, а затем вы можете отправить его через соединение сокета.

Кроме того, здесь нет никакого «сжатия» ... это просто способ конвертировать из одного представления (в ОЗУ) в другое (в «текстовом»).

About.com имеет хорошее введение засолки здесь .

Остин
источник
2
обычно можно было бы сделатьwith open('filename') as f: ...
moooeeeep
3
Кроме того, вам нужно будет сделать это, with open(filename, 'wb') as f: ...иначе вы не сможете записать в файл.
Тим Пицкер
Благодарность!! Хороший
урок
1
В общем, не очень хорошая идея использовать pickleдля передачи словаря по сети (здесь может быть лучше json). Хотя в редких случаях может пригодиться, например, multiprocessingmodule.
jfs
@Tim Pietzcker: protocol=0(по умолчанию на Python2.x) может использоваться с файлами, открытыми в текстовом режиме.
jfs
36

Травление абсолютно необходимо для распределенных и параллельных вычислений.

Допустим, вы хотите выполнить параллельное сокращение карты с помощью multiprocessing(или между узлами кластера с помощью pyina ), тогда вам нужно убедиться, что функция, которую вы хотите сопоставить с параллельными ресурсами, будет обработана. Если он не обрабатывается, вы не можете отправить его другим ресурсам другого процесса, компьютера и т. Д. Также см. Здесь хороший пример.

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

И, да, люди используют выборку, чтобы сохранить состояние вычисления, или ваш сеанс ipython , или что-то еще. Вы также можете расширить Pickler и UnPickler в pickle для сжатия bz2или, gzipесли хотите.

Майк МакКернс
источник
0

Я считаю, что это особенно полезно для больших и сложных пользовательских классов. В конкретном примере, о котором я думаю, «сбор» информации (из базы данных) для создания класса был уже полдела. Затем эта информация, хранящаяся в классе, может быть изменена пользователем во время выполнения.

Вы могли бы иметь другую группу таблиц в базе данных и написать другую функцию, чтобы просмотреть все сохраненное и записать это в новые таблицы базы данных. Затем вам нужно будет написать другую функцию, чтобы иметь возможность загружать что-то сохраненное, прочитав всю эту информацию обратно.

В качестве альтернативы вы можете выбрать весь класс как есть, а затем сохранить его в одном поле в базе данных. Затем, когда вы пойдете, чтобы загрузить его обратно, все сразу загрузится, как было раньше. Это может сэкономить много времени и кода при сохранении и извлечении сложных классов.

Цыпленок Макс
источник
-1

это своего рода сериализация. используйте cPickle, это намного быстрее, чем pickle.

import pickle
##make Pickle File
with open('pickles/corups.pickle', 'wb') as handle:
    pickle.dump(corpus, handle)

#read pickle file
with open('pickles/corups.pickle', 'rb') as handle:
    corpus = pickle.load(handle)
Паритош Ядав
источник