Frage

Ich arbeite an einem Projekt, bei dem eine große Anzahl von Objekten serialisiert und auf der Festplatte gespeichert wird pickle/cPickle.

Mit der Lebensdauer des Projekts (nach der Veröffentlichung an Kunden vor Ort) ist es wahrscheinlich, dass zukünftige Funktionen/Korrekturen die Signatur einiger unserer anhaltenden Objekte ändern müssen. Dies kann die Hinzufügung von Feldern, das Entfernen von Feldern oder die Änderung der Invarianten auf einem Datenstück sein.

Gibt es eine Standardmethode, um ein Objekt zu markieren, das als eine bestimmte Version eingelegt wird (wie serialVersionUID in Java)? Wenn ich eine Instanz von Foo Version 234 wiederherstellt, aber der aktuelle Code 236 ist, möchte ich eine Benachrichtigung über Unpickle erhalten. Sollte ich einfach meine eigene Lösung ausrollen (könnte eine Pita sein).

Vielen Dank

War es hilfreich?

Lösung

Das pickle Das Format hat keine solche Voraussetzungen. Warum machen Sie nicht einfach die "serielle Versionsnummer" Teil der Attribute des Objekts, um gleich mit dem Rest eingelegt zu werden? Dann kann die "Benachrichtigung" durch Vergleich der tatsächlichen und gewünschten Version trivial gehabt werden - sehen Sie nicht, warum es sich um eine Pita handeln sollte.

Andere Tipps

Betrachten Sie den folgenden Klassenmixin, der von Tomasz Früches vorgeschlagen wurde hier.

# versionable.py
class Versionable(object):
    def __getstate__(self):
        if not hasattr(self, "_class_version"):
            raise Exception("Your class must define _class_version class variable")
        return dict(_class_version=self._class_version, **self.__dict__)
    def __setstate__(self, dict_):
        version_present_in_pickle = dict_.pop("_class_version")
        if version_present_in_pickle != self._class_version:
            raise Exception("Class versions differ: in pickle file: {}, "
                            "in current class definition: {}"
                            .format(version_present_in_pickle,
                                    self._class_version))
        self.__dict__ = dict_

Das __getstate__ Methode wird aufgerufen von pickle beim Einweichen und __setstate__ wird durch Gurke beim Unpacken genannt. Diese Mix-In-Klasse kann als Unterklasse von Klassen verwendet werden, deren Version Sie im Auge behalten möchten. Dies ist wie folgt zu verwenden:

# bla.py
from versionable import Versionable
import pickle

class TestVersioning(Versionable):
    _class_version = 1

t1 = TestVersioning()

t_pickle_str = pickle.dumps(t1)

class TestVersioning(Versionable):
    _class_version = 2

t2 = pickle.loads(t_pickle_str) # Throws exception about wrong class version
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top