Python
14 November 2008

Консервация объектов в Python

В определенный момент любому Питон-программисту понадобится запаковать какой-то объект и спрятать его до лучших времен. Скажем, в config-файл. Или передать через сокет. Как это сделать? Разумеется, можно написать небольшой класс, который будет генерировать и парсить XML-код (кстати, следующая статья как раз будет об этом), но это — слишком большая морока.

Нет! Наш выбор — Pickle!

Преамбула


Pickle (англ. консервировать, мариновать) — модуль сериализации и десериализации объектов в Питоне для последующей их передачи.

Какие типы данных Pickle умеет запаковывать?
  • None, True, False
  • Строки (обычные или Юникод)
  • Стандартные числовые типы данных
  • Словари, списки, кортежи
  • Функции
  • Классы
Но есть одна маленькая деталь. По началу вы будете вполне довольны работой этого модуля, но позже, когда будете его использовать на high-load проектах, начнете замечать, что консервирование данных занимает больше времени, чем хотелось бы. Эту проблему решили тем, что был написан подобный модуль, но уже не на Питоне, а на С, что ускорило его производительность в тысячи раз (по заявлению разработчиков). Да, иногда модули, написанные на С, работают быстрее их питоновских аналогов, но тут есть тонкости, в которые в этой статье я позволю себе не углубляться.

Сами создатели Питона в официальной документации советуют использовать cPickle, а чтобы долго не модифицировать программу, можно подключить cPickle так:

import cPickle as pickle

Основы


Как использовать консервацию объектов? У вас есть два варианта: либо консервировать объект в строку (которую можно передать через сокет, например) либо сразу в файл.

Есть три протокола консервации:
  • Версия 0, стандартный ASCII протокол. Его следует использовать только для совместимости с ранними версиями Питона.
  • Версия 1 — примерно то же самое, используется для совместимости со старыми версиями Питона.
  • Версия 2 впервые внедрена в версии 2.3, она лучше всего запаковывает объекты, написанные в современном синтаксисе, я рекомендую использовать именно её.
Консервирование объекта в строку:

import cPickle as pickle
obj = {"one": 123, "two": [1, 2, 3]}
output = pickle.dumps(obj, 2)


Как видите, ничего сложного, объект готов к отправке.
Теперь нужно его распаковать назад. Это еще проще:

obj = pickle.loads(output)

Протокол консервирования определяется автоматически.
Давайте попробуем запаковать объект в файл.

import cPickle as pickle
obj = {"one": 123, "two": [1, 2, 3]}
output = open('data.pkl', 'wb')
pickle.dump(obj, output, 2)
output.close()


Обратите внимание, что режим записи в файл должен обязательно быть wb, то есть перезапись файла в бинарном режиме. Для чтения режим должен быть rb:

import cPickle as pickle
input = open('data.pkl', 'rb')
obj = pickle.load(input)
input.close()


Спасибо за внимание. В следующий раз я бы хотел поговорить об особенностях создания и парсинга XML-данных в Питоне.

+16
33.7k 46
Comments 45
Top of the day