Python: постепенно маршал / мариновать объект? - PullRequest
4 голосов
/ 12 марта 2009

У меня есть большой объект, который я хочу сериализовать на диск. Я считаю, маршал работает довольно хорошо, быстро и красиво.

Сейчас я создаю свой большой объект, затем вызываю marshal.dump. Я хотел бы избежать удержания большого объекта в памяти, если это возможно, - я хотел бы постепенно выгружать его при построении. Это возможно?

Объект довольно прост, словарь массивов.

Ответы [ 4 ]

4 голосов
/ 14 марта 2009

Все, что должен сделать ваш объект - это словарь списков, тогда вы сможете использовать модуль shelve . Он представляет собой словарь-интерфейс, где ключи и значения хранятся в файле базы данных, а не в памяти. Одно ограничение, которое может повлиять или не повлиять на вас, заключается в том, что ключи в объектах Shelf должны быть строками. Хранение значений будет более эффективным, если вы укажете protocol = -1 при создании объекта Shelf, чтобы использовать более эффективное двоичное представление.

4 голосов
/ 14 марта 2009

Функции hashpen и btopen модуля bsddb обеспечивают постоянный словарь-интерфейс. Возможно, вы могли бы использовать один из них вместо обычного словаря для последовательной сериализации массивов на диск?

import bsddb
import marshal

db = bsddb.hashopen('file.db')
db['array1'] = marshal.dumps(array1)
db['array2'] = marshal.dumps(array2)
...
db.close()

Чтобы получить массивы:

db = bsddb.hashopen('file.db')
array1 = marshal.loads(db['array1'])
...
0 голосов
/ 13 марта 2009

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

  1. Как вы строите объект, когда помещаете его в память?
  2. Как вам нужны ваши данные, когда они выходят из памяти?

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

big_hairy_dictionary['sample_key'] = pre_existing_array
marshal.dump({'sample_key':big_hairy_dictionary['sample_key']},'central_file')

Затем при обновлении каждый вызов marshal.load ('central_file') возвращает словарь, который вы можете использовать для обновления центрального словаря. Но на самом деле это будет полезно только в том случае, если, когда вам нужно вернуть данные, вы хотите обработать чтение «central_file» один раз для каждого ключа.

В качестве альтернативы, если вы заполняете элементы массива элементом в произвольном порядке, попробуйте:

big_hairy_dictionary['sample_key'].append(single_element)
marshal.dump(single_element,'marshaled_files/'+'sample_key')

Затем, когда вы загружаете его обратно, вам не обязательно собирать весь словарь, чтобы вернуть то, что вам нужно; вы просто вызываете marshal.load ('marshaled_files / sample_key'), пока он не возвращает None, и у вас есть все, что связано с ключом.

0 голосов
/ 12 марта 2009

Это очень сильно зависит от того, как вы строите объект. Это массив дочерних объектов? Вы можете маршалировать / мариновать каждый элемент массива при его создании. Это словарь? Та же идея применима (маршал / маринованные ключи)

Если это просто большой сложный гарри-объект, вы, возможно, захотите собрать все части объекта, а затем применить тот же процесс «строительства», когда читаете его обратно.

...