10.1 Alles nach meinem Willen!
Manchmal enthalten deine Objekte viele Referenzen zu verschiedenen Dienstobjekten, die du nicht über das Netzwerk senden willst oder nicht senden kannst: Datei-Referenzen, Datenbanken usw.
Damit Serialisierung auch in solchen Fällen funktioniert, wurde die Möglichkeit erfunden, der Klasse die Steuerung ihrer eigenen Serialisierung zu überlassen. Hierfür werden spezielle Methoden genutzt: __reduce__(), __getstate__(), __setstate__(). Diese Methoden erlauben es anzugeben, wie Objekte serialisiert und wiederhergestellt werden sollen.
Grundlegende Methoden der gesteuerten Serialisierung:
-
__reduce__(): Gibt an, wie das Objekt serialisiert werden soll. -
__getstate__(): Gibt den Zustand des Objekts für die Serialisierung zurück. -
__setstate__(self, state): Stellt das Objekt aus dem Zustand wieder her.
Im Folgenden erkläre ich diese Methoden detailliert und wie sie zusammen verwendet werden können.
10.2 Die Methode __reduce__()
Die Methode __reduce__() gibt ein Tupel zurück, das angibt, wie das Objekt serialisiert und deserialisiert werden soll. Das Tupel enthält normalerweise:
- Eine Referenz auf die Funktion oder Klasse, die zur Wiederherstellung des Objekts verwendet wird.
- Ein Tupel von Argumenten für diese Funktion oder Klasse.
- Zusätzlichen Objektzustand (falls erforderlich).
Beispiel:
import pickle
class CustomClass:
def __init__(self, value):
self.value = value
def __reduce__(self):
return (self.__class__, (self.value,))
def __repr__(self):
return f"CustomClass(value={self.value})"
# Objekt erstellen
obj = CustomClass(42)
# Objekt serialisieren
serialized_obj = pickle.dumps(obj)
print("Serialisiertes Objekt:", serialized_obj)
# Objekt deserialisieren
deserialized_obj = pickle.loads(serialized_obj)
print("Deserialisiertes Objekt:", deserialized_obj)
Standardmäßig hat die Funktion __reduce__() folgendes Verhalten:
class CustomClass:
def __init__(self, value):
self.value = value
def __reduce__(self):
# Klasse definieren
cls = self.__class__
# Konstruktorargumente
args = (self.value,)
# Objektzustand
state = self.__dict__
return (cls, args, state)
Sie gibt ein Tupel zurück, das aus drei Objekten besteht:
Referenz auf die aktuelle KlasseKonstruktorargumente (Tupel)Referenz auf den aktuellen Objektzustand
Wenn dieses Verhalten für dich passt, brauchst du __reduce__() nicht zu überschreiben.
10.3 Lesen und Schreiben von Zuständen
Die Methoden __getstate__() und __setstate__()
Diese Methoden werden verwendet, um den Zustand des Objekts während der Serialisierung und Deserialisierung zu steuern.
-
__getstate__(): Gibt den Zustand des Objekts zurück, der serialisiert werden soll. -
__setstate__(self, state): Stellt das Objekt aus dem Zustand wieder her.
Beispiel:
Angenommen, wir möchten nicht alle Felder eines Objekts speichern, sondern einige davon ausschließen. Dazu musst du in der Methode __getstate__() folgendes tun:
- Kopiere den aktuellen Zustand des Objekts (festgelegt durch das Dienstfeld
__dict__) in eine separate Variable – das Wörterbuchstate. - Entferne daraus alle Felder, die nicht serialisiert werden sollen.
- Gib das erhaltene Objekt als Ergebnis der Funktion
__getstate__()zurück.
import pickle
class CustomClass:
def __init__(self, value):
self.value = value
self.internal_state = "internal"
def __getstate__(self):
state = self.__dict__.copy()
del state['internal_state'] # Internen Zustand ausschließen
return state
def __setstate__(self, state):
self.__dict__.update(state)
self.internal_state = "restored internal" # Internen Zustand wiederherstellen
def __repr__(self):
return f"CustomClass(value={self.value}, internal_state={self.internal_state})"
# Objekt erstellen
obj = CustomClass(42)
print("Originalobjekt:", obj)
# Objekt serialisieren
serialized_obj = pickle.dumps(obj)
print("Serialisiertes Objekt:", serialized_obj)
# Objekt deserialisieren
deserialized_obj = pickle.loads(serialized_obj)
print("Deserialisiertes Objekt:", deserialized_obj)
Bei der Deserialisierung, in der Funktion __setstate__(), machen wir zwei Dinge:
- Aktualisieren den aktuellen Zustand des Objekts mit der Methode
update(). - Das Feld
internal_state(und andere nicht serialisierbare Felder) erhalten neue Werte.
GO TO FULL VERSION