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