2009-03-12 5 views
4

Ich habe ein großes Objekt, das ich auf die Festplatte serialisieren möchte. Ich finde marshal funktioniert ganz gut und ist nett und schnell.Python: Inkrementell marschieren/pickle ein Objekt?

Momentan erstelle ich mein großes Objekt und rufe dann marshal.dump auf. Ich möchte es vermeiden, das große Objekt im Speicher zu halten, wenn möglich - ich möchte es inkrementell ablegen, während ich es erstelle. Ist das möglich?

Das Objekt ist ziemlich einfach, ein Wörterbuch von Arrays.

Antwort

0

Das hängt sehr davon ab, wie Sie das Objekt bauen. Ist es ein Array von Unterobjekten? Sie können jedes Array-Element beim Erstellen marshalieren/beizen. Ist es ein Wörterbuch? Es gilt die gleiche Idee (marshal/pickle keys)

Wenn es sich nur um ein großes komplexes Harry-Objekt handelt, möchten Sie vielleicht jedes Stück des Objekts deponieren und dann anwenden, was auch immer Ihr 'Gebäude'-Prozess beim Lesen ist es zurück in.

+0

Ich habe die Frage aktualisiert. Das Objekt ist ziemlich einfach, ein Wörterbuch von Arrays. Jedes Array ist ziemlich klein.Würde ich jedes einzelne Array marshalen? In die gleiche Datei? – Parand

0

Sie sollten in der Lage sein, das Element Stück für Stück in die Datei zu entleeren. Die zwei Entwurfsfragen, die Einebnung benötigen, sind:

  1. Wie erstellen Sie das Objekt, wenn Sie es in Arbeitsspeicher versetzen?
  2. Wie benötigen Sie Ihre Daten, wenn sie nicht mehr verfügbar sind?

Wenn Ihr Build-Prozess das gesamte Array mit einem bestimmten Schlüssel zu einer Zeit zugeordnet auffüllt, können Sie Dump nur das Schlüssel: Feldpaar in einer Datei als separates Wörterbuch:

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

dann auf Update , jeder Aufruf von marshal.load ('central_file') gibt ein Wörterbuch zurück, mit dem Sie ein zentrales Wörterbuch aktualisieren können. Aber das wird wirklich nur hilfreich sein, wenn Sie, wenn Sie die Daten zurück benötigen, einmal pro Taste das Lesen von "central_file" behandeln wollen.

Alternativ kann, wenn Sie Arrays Element in keiner bestimmten Reihenfolge durch das Element bevölkern, vielleicht versuchen:

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

Dann, wenn Sie es wieder laden, müssen Sie nicht unbedingt das gesamte Wörterbuch bauen zu bekommen zurück, was du brauchst; Sie rufen einfach marshal.load ('marshaled_files/sample_key') auf, bis es None zurückgibt, und Sie haben alles mit dem Schlüssel verknüpft.

4

Die Funktionen 'hashopen' und 'btopen' des bsddb-Moduls bieten eine persistente wörterbuchähnliche Schnittstelle. Vielleicht könnten Sie eines dieser anstelle eines regulären Wörterbuchs verwenden, um die Arrays inkrementell seriell zu serialisieren?

import bsddb 
import marshal 

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

Um die Arrays abrufen:

db = bsddb.hashopen('file.db') 
array1 = marshal.loads(db['array1']) 
... 
4

Alles Ihr Objekt hat ein Wörterbuch von Listen zu tun ist, sein, dann können Sie in der Lage sein, die shelve module zu verwenden. Es stellt eine wörterbuchähnliche Schnittstelle dar, in der die Schlüssel und Werte in einer Datenbankdatei statt im Speicher gespeichert werden. Eine Einschränkung, die Sie betreffen kann oder nicht, ist, dass Schlüssel in Shelf-Objekten Strings sein müssen. Wertspeicher wird effizienter sein, wenn Sie beim Erstellen des Shelf-Objekts protocol = -1 angeben, damit es eine effizientere binäre Darstellung verwendet.

+0

Warum wurde das nicht als korrekt markiert? Um diese Antwort zu ergänzen, stellen Sie sicher, dass Sie über das Zurückschreiben/Änderbarkeit von zurückgestellten Objekten Bescheid wissen. – Karthick