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

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

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

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

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

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 обрабатывает эти случаи без проблем)
  • Здесь нет кода для очистки каталога / удаления файлов.
Другие вопросы по тегам