Я хочу, чтобы мой класс реализовал функции сохранения и загрузки, которые просто делают рассол класса. Но, по-видимому, вы не можете использовать "я" ниже. Как вы можете это сделать?
self = cPickle.load(f)
cPickle.dump(self,f,2)
Я хочу, чтобы мой класс реализовал функции сохранения и загрузки, которые просто делают рассол класса. Но, по-видимому, вы не можете использовать "я" ниже. Как вы можете это сделать?
self = cPickle.load(f)
cPickle.dump(self,f,2)
Это то, что я закончил делать. Обновление __dict__
означает, что мы сохраняем любые новые переменные-члены, которые я добавляю в класс, и просто обновляю те, которые были там, когда объект был последним. Это кажется самым простым, сохраняя код сохранения и загрузки внутри самого класса, поэтому вызывающий код просто выполняет object.save().
def load(self):
f = open(self.filename, 'rb')
tmp_dict = cPickle.load(f)
f.close()
self.__dict__.update(tmp_dict)
def save(self):
f = open(self.filename, 'wb')
cPickle.dump(self.__dict__, f, 2)
f.close()
Часть дампа должна работать, как вы предложили. для части загрузки вы можете определить @classmethod, который загружает экземпляр из заданного файла и возвращает его.
@classmethod
def loader(cls,f):
return cPickle.load(f)
то вызывающий пользователь сделает что-то вроде:
class_instance = ClassName.loader(f)
Если вы хотите, чтобы ваш класс обновлялся из сохраненного пика... вы в значительной степени должны использовать __dict__.update
, как вы в своем собственном ответе. Однако это похоже на кошку, преследующую его хвост... поскольку вы спрашиваете экземпляр по существу "reset" с предшествующим состоянием.
Там есть небольшая настройка вашего ответа. Вы можете развести self
.
>>> import dill
>>> class Thing(object):
... def save(self):
... return dill.dumps(self)
... def load(self, obj):
... self.__dict__.update(dill.loads(obj).__dict__)
...
>>> t = Thing()
>>> t.x = 1
>>> _t = t.save()
>>> t.x = 2
>>> t.x
2
>>> t.load(_t)
>>> t.x
1
Я использовал loads
и dumps
вместо load
и dump
, потому что я хотел, чтобы pickle сохранялся в строке. Использование load
и dump
в файле также работает.
И, фактически, я могу использовать dill
для разбора экземпляра класса в файл, для последующего использования... даже если класс определен в интерактивном режиме. Продолжение сверху...
>>> with open('self.pik', 'w') as f:
... dill.dump(t, f)
...
>>>
затем остановка и перезапуск...
Python 2.7.10 (default, May 25 2015, 13:16:30)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> with open('self.pik', 'r') as f:
... t = dill.load(f)
...
>>> t.x
1
>>> print dill.source.getsource(t.__class__)
class Thing(object):
def save(self):
return dill.dumps(self)
def load(self, obj):
self.__dict__.update(dill.loads(obj).__dict__)
>>>
Я использую dill
, который доступен здесь: https://github.com/uqfoundation
Ниже приведен пример того, как распиливать экземпляр здесь, в документах. (Ищите вниз для примера "TextReader" ). Идея состоит в том, чтобы определить методы __getstate__
и __setstate__
, которые позволяют определить, какие данные нужно мариновать, и как использовать эти данные для повторного создания объекта.
Как насчет написания класса с именем Serializable, который будет реализовывать дамп и нагрузку и сделать ваш класс унаследованным от него?