2010-02-25 1 views
2

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

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

Любые предложения?

EDIT - РЕШЕНИЕ:

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

# 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) 

ответ

2

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

+0

Отлично! Я получил работу. Ваше предложение привело меня к http://effbot.org/librarybook/copy-reg.htm, в котором представлены несколько отличных примеров. –

1

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

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

+0

Для массивов я бы преобразовал их в большой строковый объект с '.tostring()', который является всего лишь копией байтов в памяти, представляющих массив. –

+0

С помощью этого подхода вы также хотели бы включить тип файла массива . Я пробовал это но я столкнулся с проблемами получения состояния typecode в незакрашенном объекте. Я пытался выяснить, что «__initargs__» мало пользы ... Я думаю, что я собираюсь использовать метод «copy_req». –

1

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

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) 

выглядит отвалы даже не включает информацию о typecode..or даже данные :(

>>> a=array.array('c','abcdefghijkl') 
>>> pickle.dumps(a,2)                                            
'\x80\x02carray\narray\nq\x01)\x81q\x02.' 
>>> 
+0

Да, это, похоже, подтверждает эту ошибку из списка рассылки python: http://mail.python.org/pipermail/python-bugs-list/2006-January/031597.html «smarts» были добавлены в 2.5 –

Смежные вопросы