Серіалізація Python - навіщо маринувати?


87

Я зрозумів, що маринування Python - це спосіб "зберігати" Python-об'єкт таким чином, щоб він поважав програмування об'єктів - на відміну від виводу, записаного у файлі txt або БД.

Чи є у вас додаткова інформація або посилання на такі моменти:

  • де «зберігаються» мариновані предмети?
  • чому травлення збереження репрезентації об'єкта більше, ніж, скажімо, зберігання в БД?
  • чи можу я отримати замариновані об'єкти з одного сеансу оболонки Python до іншого?
  • чи є у вас вагомі приклади, коли серіалізація корисна?
  • чи передбачає серіалізація засоленням "стиснення" даних?

Іншими словами, я шукаю документ про маринування - Python.doc пояснює, як реалізувати соління, але, здається, не заглиблюється в подробиці щодо використання та необхідності серіалізації.


Моє здогадування було б зберегти стан для подальшого відновлення або поділитися / скопіювати об'єкт в інший час виконання python.
synthesizerpatel

13
На багато ваших запитань відповідає стаття Вікіпедії про серіалізацію: en.wikipedia.org/wiki/Serialization
NPE

5
ти запитуєш, навіщо мені потрібен Pickle для серіалізації в Python? вірніше, що все-таки (мета) серіалізації? .
moooeeeep

Можливо, непогано згадати проблеми безпеки з засоленням. Приклади можна знайти в документації та в численних запитаннях, подібних до цього .
djvg

Відповіді:


99

Протруювання - це спосіб перетворити об’єкт пітона (список, dict тощо) у потік символів. Ідея полягає в тому, що цей символьний потік містить всю інформацію, необхідну для реконструкції об’єкта в іншому сценарії python.

Що стосується того, де зберігається замаринована інформація, зазвичай слід зробити:

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

Це збереже мариновану версію нашого varдикту у файлі "ім'я файлу". Потім, в іншому сценарії, ви можете завантажити цей файл у змінну, і словник буде відтворений:

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: ...або ви не зможете записати у файл.
Тім Пітцкер

Дякую!! Цей на тему управління персистенцією Python приємний, тут
kiriloff

1
Взагалі, це не дуже гарна ідея використовувати pickleдля передачі словника по мережі (json може бути краще тут). Хоча в рідкісних випадках це може бути корисним, наприклад, multiprocessingмодуль.
jfs

@Tim Pietzcker: protocol=0(за замовчуванням на Python2.x) можна використовувати з файлами, відкритими в текстовому режимі.
jfs

36

Соління є абсолютно необхідним для розподілених та паралельних обчислень.

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

Для цього я використовую кріп , який може серіалізувати майже все, що є в python. Dill також має кілька хороших інструментів, які допоможуть вам зрозуміти, що спричиняє невдачу вашого травлення, коли ваш код не вдається.

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


0

Я вважаю, що це особливо корисно для великих та складних користувацьких класів. У конкретному прикладі, про який я думаю, "збирання" інформації (з бази даних) для створення класу було вже половиною успіху. Тоді ця інформація, що зберігається у класі, може бути змінена під час виконання користувачем.

Ви можете мати іншу групу таблиць у базі даних і написати іншу функцію, щоб переглядати все збережене та записувати її до нових таблиць бази даних. Тоді вам потрібно буде написати іншу функцію, щоб мати можливість завантажити щось збережене, прочитавши всю цю інформацію назад.

Крім того, ви можете замаринувати весь клас як є, а потім зберегти його в одному полі бази даних. Потім, коли ви підете завантажувати його назад, воно все завантажиться назад відразу, як це було раніше. Це може в кінцевому підсумку заощадити багато часу та коду під час збереження та отримання складних класів.


-1

це свого роду серіалізація. використовуйте cPickle набагато швидше, ніж соління.

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.