クラスに、クラスのピクルを単純に行うSave関数とLoad関数を実装してもらいたい。しかし、どうやら以下の方法で「自己」を使用することはできません。どうすればできますか?
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
を使用する必要があります。猫が尻尾を追いかけているようなものですが、インスタンスに以前の状態で本質的に「リセット」するように要求しています。
あなたの答えには少し微調整があります。実際に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__
メソッド。ピクル化する必要のあるデータと、そのデータを使用してオブジェクトを再インスタンス化する方法を定義できます。