ピクル可能にするためには、クラスが__reduce__
メソッドを上書きし、文字列またはタプルを返す必要があることを知っています。
この機能はどのように機能しますか? __reduce__
の正確な使用法は何ですか?いつ使用されますか?
私はこれを説明するのに一生懸命かどうか見ます。
オブジェクトをpickle化しようとすると、シリアル化できないプロパティがいくつかあります。たとえば、開いているファイルハンドルこの場合、pickleはオブジェクトの処理方法を認識せず、エラーをスローします。
これらのタイプのオブジェクトをクラス内でネイティブに直接処理する方法をpickleモジュールに伝えることができます。単一のプロパティを持つオブジェクトの例を作成してみましょう。開いているファイルハンドル:
_import pickle
class test(object):
def __init__(self, file_path = 'test1234567890.txt'):
self.some_file_i_have_opened = open(file_path, 'wb') # An open file in write mode.
my_test = test()
# Now, watch what happens when we try to pickle this object:
pickle.dumps(my_test)
_
それは失敗し、トレースバックを与える必要があります:
_Traceback (most recent call last):
File "<stdin>", line 1, in <module>
--- snip snip a lot of lines ---
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle file objects
_
ただし、test
class
に___reduce__
_メソッドを定義した場合、pickleはこのオブジェクトをシリアル化する方法を知っていたはずです。
_import pickle
class test(object):
def __init__(self, file_path = 'test1234567890.txt'):
self._file_name_we_opened = file_path # Used later in __reduce__
self.some_file_i_have_opened = open(self._file_name_we_opened, 'wb') # An open file in write mode.
def __reduce__(self):
return (self.__class__, (self._file_name_we_opened, )) # we return a Tuple of class_name to call, and optional parameters to pass when re-creating
my_test = test()
saved_object = pickle.dumps(my_test)
print repr(saved_object) # Just print the representation of the string of the object, because it contains newlines.
_
これにより、次のような結果が得られます。_"c__main__\ntest\np0\n(S'test1234567890.txt'\np1\ntp2\nRp3\n."
_。これは、開いているファイルハンドルでオブジェクトを再作成するために使用できます。
_print vars(pickle.loads(saved_object))
_
通常、大きな混乱は___reduce__
_が返すオブジェクトのタイプにあります。あなたはドキュメントのページでどのタイプのオブジェクトreduceが返すべきかについてもう少し読むことができます: https://docs.python。 org/3/library/pickle.html#object。reduce ですが、通常、少なくとも2つのタプルが必要です。
self.__class__
_他にもオプションのアイテムがありますが、それらについてはすべてドキュメントで読む必要があります。
お役に立てば幸いです。