CodeGym /Corsi /Python SELF IT /Gestione della serializzazione

Gestione della serializzazione

Python SELF IT
Livello 22 , Lezione 2
Disponibile

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 corrente
  • Argomenti 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:

  1. Copiare lo stato corrente dell'oggetto (dato dal campo di servizio __dict__) in una variabile separata: il dizionario state.
  2. Eliminare da esso tutti i campi che non devono essere serializzati.
  3. 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:

  1. Aggiorniamo lo stato corrente dell'oggetto utilizzando il metodo update().
  2. Il campo internal_state (e altri campi non serializzabili) riceve nuovi valori.
1
Sondaggio/quiz
Lavorare con le directory, livello 22, lezione 2
Non disponibile
Lavorare con le directory
Lavorare con le directory
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION