Pickling array.array в версии 2.4 с использованием cPickle - PullRequest
2 голосов
/ 26 февраля 2010

Я работаю над проектом, построенным на Python 2.4 (это встроенный проект на Python, поэтому у меня нет выбора по используемой версии Python). Во всем приложении мы используем array.array для хранения данных.

Поддержка выбора объектов array.array была добавлена ​​в picklecPickle) в версии 2.5. У нас есть жизнеспособный обходной путь в версии 2.4, когда мы используем чистый класс Python Pickle (мы используем подкласс Pickler / Unpickler для обработки массивов), но это не работает с cPickle (нам это нужно из-за проблем с производительностью).

Есть предложения?

РЕДАКТИРОВАТЬ - РЕШЕНИЕ:

Это последний код, который работает (спасибо за предложения):

# Add serialization for array objects
def array_unpickler(data):
    return array.array(data[0], data[1:])
def array_pickler(arr):
    return array_unpickler, ("%s%s" % (arr.typecode, arr.tostring()),)
copy_reg.pickle(array.ArrayType, array_pickler, array_unpickler)

Ответы [ 3 ]

2 голосов
/ 26 февраля 2010

Вы можете использовать стандартный библиотечный модуль copy_reg для регистрации функций для работы с экземплярами выбора типов, которые изначально не поддерживают выборку;cPickle будет использовать ваши зарегистрированные функции там, где это необходимо.Я бы применил именно этот подход «крючка» к вашему требованию по травлению экземпляров array.array.

1 голос
/ 26 февраля 2010

Похоже, вы можете их засолить, но вы не можете распечатать результат

Python 2.4.5 (#2, Jan 21 2010, 20:05:55) 
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cPickle as pickle
>>> import array
>>> a=array.array('i','12345678')
>>> pickle.dumps(a,2)
'\x80\x02carray\narray\nq\x01)\x81q\x02.'
>>> b=pickle.loads(_)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: array() takes at least 1 argument (0 given)

Похоже, что в дампах нет даже информации о типе типа .. или даже данных: (

>>> a=array.array('c','abcdefghijkl') 
>>> pickle.dumps(a,2)                                                                                                                                                                             
'\x80\x02carray\narray\nq\x01)\x81q\x02.'
>>> 
1 голос
/ 26 февраля 2010

Я не уверен, что тип массива можно дополнить методом __reduce__ (возможно, с помощью подкласса), но вы всегда можете попробовать преобразовать ваши массивы в последовательности и обратно ... если встроенное расширение механизм не будет работать для вас. (Хак)

Я не пробовал этого раньше, но вы можете попробовать добавить поддержку через copy_reg ... по сути тот же результат, что и реализация __reduce__ в вашем собственном классе или подклассе, но немного чище.

...