Как я могу рассортировать иерархию объектов, * каждый объект обычно имеет свой отдельный файл*, чтобы сохранить быстро?


Я хочу использовать pickle, в частности cPickle, для сериализации данных моих объектов в виде папки файлов, представляющих модули, проекты, объекты модулей, объекты сцен и т. д. Есть ли простой способ сделать это?

Таким образом, распаковка будет немного сложнее, поскольку каждый родительский объект хранит ссылку на дочерние / родственные объекты при запуске, но данные pickle родителя будут содержать путь к файлу для объекта.

Я начал с класса PathUtil, который наследуют все классы, но уже запущен в вопросы. Кто-нибудь решал подобную проблему/функцию сохранения / восстановления файлов данных?

Чем прозрачнее он работает с существующим кодом, тем лучше. Например, если использование мета-класса __call__ сделает существующий синтаксис конструктора неизменным, это будет плюсом. Например, Статический __call__ сначала проверит файл pickle и загрузит его , если он существует, а если нет, то построит конструкцию по умолчанию.

1 2

1 ответ:

Можно переопределить __getstate__ для записи в новый файл pickle и возврата его пути, а также __setstate__ для распаковки файла.

import pickle, os

DIRNAME = 'path/to/my/pickles/'

class AutoPickleable:

    def __getstate__(self):
        state = dict(self.__dict__)
        path = os.path.join(DIRNAME, str(id(self)))
        with open(path, 'wb') as f:
            pickle.dump(state, f)
        return path

    def __setstate__(self, path):
        with open(path, 'b') as f:
            state = pickle.load(f)
        self.__dict__.update(state)

Теперь каждый тип, который должен иметь это специальное поведение автоматического рассола, должен быть подклассом AutoPickleable.

Когда вы хотите сбросить файлы, вы можете сделать pickle.dumps(obj) или copy.deepcopy(obj) и игнорировать результат.

Распаковка работает как обычно (pickle.load). Если вы хотите восстановить объекты из пути к файлу (а не из результатов pickle.dumps), это немного сложнее. Дайте мне знать, если ты хочешь этого, а я добавлю подробности. В любом случае, если вы обернете свой объект AutoPickleable" стандартным " объектом и выполните все операции маринования на нем, все это должно работать.

Существует несколько потенциальных проблем с этим подходом, но для "чистого" случая, такого как тот, который вы описываете, он может сработать.

Некоторые примечания:

  • Нет способа "динамически" указать каталог для записи. Он должен быть глобально доступен и установлен перед маринованием. операция
  • вероятно, не будет работать, если несколько объектов содержат ссылки на один и тот же объект AutoPickleable, или если у вас есть циклические ссылки (в общем, pickle обрабатывает эти случаи без проблем)
  • здесь нет кода для очистки каталога / удаления файлов.