Frage

Ich weiß, dass eine Klasse überschreiben muss __reduce__ Methode, und sie muss String oder Tupel zurückgeben.

Wie funktioniert diese Funktion? Was die genaue Verwendung von __reduce__? Wann wird es verwendet?

War es hilfreich?

Lösung

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:

  1. Eine leere Objektklasse zum Anrufen. In diesem Fall, self.__class__
  2. 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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top