10.1 Tutto secondo me!
A volte nei tuoi oggetti ci sono molti riferimenti a vari oggetti di servizio che non vuoi trasmettere in rete, o che non è possibile trasmettere in rete: riferimenti a file, database ecc.
Per far funzionare la serializzazione anche in questi casi, hanno pensato di dare alla classe la possibilità di gestire la propria serializzazione. Per questo si utilizzano metodi speciali: __reduce__(), __getstate__(), __setstate__(). Questi metodi permettono di specificare come gli oggetti devono essere serializzati e ripristinati.
Metodi principali per la gestione della serializzazione:
-
__reduce__(): Specifica come l'oggetto deve essere serializzato. -
__getstate__(): Restituisce lo stato dell'oggetto per la serializzazione. -
__setstate__(self, state): Ripristina l'oggetto dallo stato.
Di seguito spiegherò in dettaglio come utilizzarli insieme.
10.2 Metodo __reduce__()
Il metodo __reduce__() restituisce una tupla, che specifica come l'oggetto deve essere serializzato e deserializzato. La tupla contiene solitamente:
- Un riferimento a una funzione o classe, che sarà utilizzata per il ripristino dell'oggetto.
- Una tupla di argomenti per questa funzione o classe.
- Stato aggiuntivo dell'oggetto (se necessario).
Esempio:
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})"
# Creazione dell'oggetto
obj = CustomClass(42)
# Serializzazione dell'oggetto
serialized_obj = pickle.dumps(obj)
print("Oggetto serializzato:", serialized_obj)
# Deserializzazione dell'oggetto
deserialized_obj = pickle.loads(serialized_obj)
print("Oggetto deserializzato:", deserialized_obj)
Di default, la funzione __reduce__() ha questo comportamento:
class CustomClass:
def __init__(self, value):
self.value = value
def __reduce__(self):
# Definizione della classe
cls = self.__class__
# Argomenti del costruttore
args = (self.value,)
# Stato dell'oggetto
state = self.__dict__
return (cls, args, state)
Restituisce una tupla composta da tre oggetti:
Riferimento alla classe correnteArgomenti del costruttore (tupla)Riferimento allo stato corrente dell'oggetto
Se questo comportamento ti va bene, puoi evitare di sovrascrivere __reduce__().
10.3 Lettura e scrittura dello stato
Metodi __getstate__() e __setstate__()
Questi metodi sono utilizzati per gestire lo stato dell'oggetto durante la serializzazione e deserializzazione.
-
__getstate__(): Restituisce lo stato dell'oggetto, che deve essere serializzato. -
__setstate__(self, state): Ripristina l'oggetto dallo stato.
Esempio:
Supponiamo di voler conservare non tutti i campi dell'oggetto, ma escludere alcuni di essi. Per questo nel metodo __getstate__() bisogna:
- Copiare lo stato corrente dell'oggetto (dato dal campo di servizio
__dict__) in una variabile separata: il dizionariostate. - Eliminare da esso tutti i campi che non devono essere serializzati.
- Restituire l'oggetto ottenuto come risultato della funzione
__getstate__().
import pickle
class CustomClass:
def __init__(self, value):
self.value = value
self.internal_state = "interno"
def __getstate__(self):
state = self.__dict__.copy()
del state['internal_state'] # Escludiamo lo stato interno
return state
def __setstate__(self, state):
self.__dict__.update(state)
self.internal_state = "interno ripristinato" # Ripristiniamo lo stato interno
def __repr__(self):
return f"CustomClass(value={self.value}, internal_state={self.internal_state})"
# Creazione dell'oggetto
obj = CustomClass(42)
print("Oggetto originale:", obj)
# Serializzazione dell'oggetto
serialized_obj = pickle.dumps(obj)
print("Oggetto serializzato:", serialized_obj)
# Deserializzazione dell'oggetto
deserialized_obj = pickle.loads(serialized_obj)
print("Oggetto deserializzato:", deserialized_obj)
Durante la deserializzazione, nella funzione __setstate__(), facciamo due cose:
- Aggiorniamo lo stato corrente dell'oggetto utilizzando il metodo
update(). - Il campo
internal_state(e altri campi non serializzabili) riceve nuovi valori.
GO TO FULL VERSION