Как я могу рассортировать иерархию объектов, * каждый объект обычно имеет свой отдельный файл*, чтобы сохранить быстро?
Я хочу использовать pickle, в частности cPickle, для сериализации данных моих объектов в виде папки файлов, представляющих модули, проекты, объекты модулей, объекты сцен и т. д. Есть ли простой способ сделать это?
Таким образом, распаковка будет немного сложнее, поскольку каждый родительский объект хранит ссылку на дочерние / родственные объекты при запуске, но данные pickle родителя будут содержать путь к файлу для объекта.
Я начал с класса 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 обрабатывает эти случаи без проблем)- здесь нет кода для очистки каталога / удаления файлов.