Ich möchte, dass meine Klasse Save and Load-Funktionen implementiert, die einfach ein Pickle der Klasse ausführen. Aber anscheinend können Sie "Selbst" nicht wie folgt verwenden. Wie kannst du das tun?
self = cPickle.load(f)
cPickle.dump(self,f,2)
Ich möchte, dass meine Klasse Save and Load-Funktionen implementiert, die einfach ein Pickle der Klasse ausführen. Aber anscheinend können Sie "Selbst" nicht wie folgt verwenden. Wie kannst du das tun?
self = cPickle.load(f)
cPickle.dump(self,f,2)
Antworten:
Das habe ich letztendlich getan. Durch das Aktualisieren der __dict__
Mittel behalten wir alle neuen Mitgliedsvariablen bei, die ich der Klasse hinzufüge, und aktualisieren nur diejenigen, die vorhanden waren, als das Objekt zuletzt ausgewählt wurde. Es scheint am einfachsten zu sein, wenn der Speicher- und Ladecode in der Klasse selbst beibehalten wird, sodass beim Aufrufen von Code nur ein object.save () ausgeführt wird.
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
und save
in Kleinbuchstaben python.org/dev/peps/pep-0008/#function-names
merge
. Sie sollten anrufen, self.__dict__.clear()
bevor Sie anrufenself.__dict__.update(..)
Der Dump-Teil sollte wie vorgeschlagen funktionieren. Für den Ladeteil können Sie eine @ classmethod definieren , die eine Instanz aus einer bestimmten Datei lädt und zurückgibt.
@classmethod
def loader(cls,f):
return cPickle.load(f)
dann würde der Anrufer so etwas tun wie:
class_instance = ClassName.loader(f)
Wenn Sie möchten, dass sich Ihre Klasse von einer gespeicherten Gurke selbst aktualisiert, müssen Sie so ziemlich alles verwenden __dict__.update
, wie Sie es in Ihrer eigenen Antwort getan haben. Es ist jedoch so, als würde eine Katze ihren Schwanz jagen ... während Sie die Instanz bitten, sich im Wesentlichen auf den vorherigen Zustand zurückzusetzen.
Ihre Antwort hat eine leichte Änderung. Sie können tatsächlich einlegen 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
Ich habe loads
und benutztdumps
anstelle von load
und verwendet, dump
weil ich wollte, dass die Gurke in einer Zeichenfolge gespeichert wird. Das Verwenden von load
und dump
zu einer Datei funktioniert auch. Und tatsächlich kann ich dill
eine Klasseninstanz zur späteren Verwendung in eine Datei einfügen ... selbst wenn die Klasse interaktiv definiert ist. Fortsetzung von oben ...
>>> with open('self.pik', 'w') as f:
... dill.dump(t, f)
...
>>>
dann anhalten und neu starten ...
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__)
>>>
Ich verwende dill
, das hier verfügbar ist: https://github.com/uqfoundation
In den Dokumenten finden Sie ein Beispiel für das Auswählen einer Instanz . (Suchen Sie nach dem Beispiel "TextReader"). Die Idee ist , zu definieren __getstate__
und __setstate__
Methoden, mit denen Sie definieren , welche Daten Bedürfnisse gebeizt werden, und wie diese Daten zu verwenden , um Wieder instantiate das Objekt.
So habe ich es gemacht. Der Vorteil ist, dass Sie kein neues Objekt erstellen müssen. Sie können es einfach direkt laden.
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)
Wie man es benutzt:
class_object.save()
filename = class_object.filename
del class_object
class_object = ClassName.load(filename)