Wenn Sie versuchen, ein Objekt zu wählen, gibt es möglicherweise einige Eigenschaften, die nicht gut serialisieren. Ein Beispiel hierfür ist ein geöffneter Dateihandle. Pickle weiß nicht, wie man mit dem Objekt umgeht, und wirft einen Fehler.
Sie können dem Gurkenmodul feststellen, wie diese Art von Objekten innerhalb einer Klasse direkt behandelt werden. Sehen wir uns ein Beispiel für ein Objekt an, das eine einzelne Eigenschaft hat. Ein geöffneter Dateihandle:
import pickle
class Test(object):
def __init__(self, file_path="test1234567890.txt"):
# An open file in write mode
self.some_file_i_have_opened = open(file_path, 'wb')
my_test = Test()
# Now, watch what happens when we try to pickle this object:
pickle.dumps(my_test)
Es sollte scheitern und ein Traceback geben:
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
Hen wir jedoch a definiert haben __reduce__
Methode in unserer Test
Klasse, Pickle hätte gewusst, wie man dieses Objekt serialisieren:
import pickle
class Test(object):
def __init__(self, file_path="test1234567890.txt"):
# Used later in __reduce__
self._file_name_we_opened = file_path
# An open file in write mode
self.some_file_i_have_opened = open(self._file_name_we_opened, 'wb')
def __reduce__(self):
# we return a tuple of class_name to call,
# and optional parameters to pass when re-creating
return (self.__class__, (self._file_name_we_opened, ))
my_test = Test()
saved_object = pickle.dumps(my_test)
# Just print the representation of the string of the object,
# because it contains newlines.
print(repr(saved_object))
Dies sollte Ihnen so etwas geben wie: "c__main__\nTest\np0\n(S'test1234567890.txt'\np1\ntp2\nRp3\n."
, mit der das Objekt mit geöffneten Dateihandles nachgebildet werden kann:
print(vars(pickle.loads(saved_object)))
Im Allgemeinen die __reduce__
Die Methode muss ein Tupel mit mindestens zwei Elementen zurückgeben:
- Eine leere Objektklasse zum Anrufen. In diesem Fall,
self.__class__
- Ein Tupel von Argumenten, um an den Klassenkonstruktor zu gelangen. Im Beispiel handelt es sich um eine einzelne Zeichenfolge, die der Pfad zur geöffneten Datei ist.
Konsultieren Sie die Dokumente Für eine detaillierte Erklärung dessen, was die sonst noch __reduce__
Methode kann zurückkehren.