Вопрос

Я работаю над проектом, где у нас есть большое количество объектов, сериализуемых и хранящихся на диск с использованием pickle/cPickle.

По мере развития жизни проекта (после выпуска клиентов в полевых условиях) вполне вероятно, что будущие функции/исправления потребуют, чтобы мы изменили подпись некоторых из наших постоянных объектов. Это может быть добавление полей, удаление полей или даже просто изменение инвариантов на части данных.

Есть ли стандартный способ отметить объект, который будет ослаблен как имея определенную версию (например, serialVersionUID в Java)? По сути, если я восстанавливаю экземпляр FOO версии 234, но текущий код составляет 236, я хочу получить некоторое уведомление о том, что уведомляет. Стоит ли просто пойти дальше и развернуть свое собственное решение (может быть лаваша).

Спасибо

Это было полезно?

Решение

А pickle Формат не имеет такого условия. Почему бы вам просто не сделать «номер серийной версии» частью атрибутов объекта, чтобы быть маринованным вместе с остальными? Тогда «уведомление» может быть тривиально иметь, сравнивая реальную и желаемую версию - не понимайте, почему это должно быть лаваш.

Другие советы

Рассмотрим следующий класс Mixin, предложенный Tomasz Früboes здесь.

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

А __getstate__ метод вызывается pickle При марине и __setstate__ Вызывает маринованную часть. Этот класс Mix-In можно использовать в качестве подкласса классов, версия которой вы хотите отслеживать. Это должно использоваться следующим образом:

# 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top