Я хочу, чтобы мой класс реализовывал функции сохранения и загрузки, которые просто делают рассол класса. Но, по-видимому, вы не можете использовать «я», как показано ниже. Как вы можете это сделать?
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()
load
и save
строчными буквами python .org/dev/peps/pep-0008/#названия-функций
- person Adam Matan; 17.06.2015
merge
. Вы должны позвонить self.__dict__.clear()
, прежде чем звонить self.__dict__.update(..)
- person deepelement; 16.08.2017
Часть дампа должна работать, как вы предложили. для части загрузки вы можете определить @classmethod, который загружает экземпляр из данный файл и возвращает его.
@classmethod
def loader(cls,f):
return cPickle.load(f)
тогда вызывающий абонент сделает что-то вроде:
class_instance = ClassName.loader(f)
Если вы хотите, чтобы ваш класс обновлялся из сохраненного рассола… вам в значительной степени нужно использовать __dict__.update
, как вы сделали в своем собственном ответе. Однако это похоже на то, как кошка гоняется за своим хвостом… поскольку вы просите экземпляр по существу «сбросить» себя с предыдущим состоянием.
В вашем ответе есть небольшая поправка. На самом деле вы можете замариновать 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
, потому что хотел, чтобы рассол сохранялся в строку. Использование 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__
, которые позволяют вам определить, какие данные необходимо обработать, и как использовать эти данные для повторного создания экземпляра объекта.
Вот как я это сделал. Преимущество в том, что вам не нужно создавать новый объект. Вы можете просто загрузить его напрямую.
def save(self):
with open(self.filename, 'wb') as f:
pickle.dump(self, f)
@classmethod
def load(cls, filename):
with open(filename, 'rb') as f:
return pickle.load(f)
Как это использовать:
class_object.save()
filename = class_object.filename
del class_object
class_object = ClassName.load(filename)
Ниже я обновил ответ полностью работающим минимальным примером. Это может быть адаптировано к вашим собственным потребностям.
import pickle
class Test:
def __init__(self, something, filename) -> None:
self.something = something
self.filename = filename
def do_something(self) -> None:
print(id(self))
print(self.something)
def save(self):
with open(self.filename, 'wb') as f:
pickle.dump(self, f)
@classmethod
def load(cls, filename):
with open(filename, 'rb') as f:
return pickle.load(f)
test_object = Test(44, "test.pkl")
test_object.do_something()
test_object.save()
filename = test_object.filename
del test_object
recovered_object = Test.load(filename)
recovered_object.do_something()
self
в рассоле при дампе.
- person JAWS007; 09.07.2021