10.1 Tout se fera à ma manière !
Parfois, tes objets contiennent beaucoup de références à différents objets de service que tu ne veux pas transmettre sur le réseau, ou qui ne peuvent pas être transmis sur le réseau : références à des fichiers, des bases de données, etc.
Pour que la sérialisation fonctionne dans de tels cas, on a eu l'idée de donner à la classe
la possibilité de gérer elle-même sa sérialisation. Pour cela
on utilise des méthodes spéciales : __reduce__()
,
__getstate__()
, __setstate__()
. Ces méthodes
permettent d'indiquer comment les objets doivent être sérialisés et
restaurés.
Méthodes principales de la sérialisation contrôlée :
-
__reduce__()
: Indique comment l'objet doit être sérialisé. -
__getstate__()
: Retourne l'état de l'objet pour la sérialisation. -
__setstate__(self, state)
: Restaure l'objet à partir de l'état.
Je vais te parler d'eux plus en détail ci-dessous, et comment les utiliser ensemble.
10.2 Méthode __reduce__()
La méthode __reduce__()
retourne un tuple,
qui indique comment l'objet doit être sérialisé et
désérialisé. Le tuple contient généralement :
- Une référence à la fonction ou classe qui sera utilisée pour restaurer l'objet.
- Un tuple d'arguments pour cette fonction ou classe.
- Un état supplémentaire de l'objet (si nécessaire).
Exemple :
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})"
# Création de l'objet
obj = CustomClass(42)
# Sérialisation de l'objet
serialized_obj = pickle.dumps(obj)
print("Objet sérialisé :", serialized_obj)
# Désérialisation de l'objet
deserialized_obj = pickle.loads(serialized_obj)
print("Objet désérialisé :", deserialized_obj)
Par défaut, la fonction __reduce__()
a ce comportement :
class CustomClass:
def __init__(self, value):
self.value = value
def __reduce__(self):
# Définition de la classe
cls = self.__class__
# Arguments du constructeur
args = (self.value,)
# État de l'objet
state = self.__dict__
return (cls, args, state)
Elle retourne un tuple composé de trois objets :
Référence à la classe actuelle
Arguments du constructeur (tuple)
Référence à l'état actuel de l'objet
Si ce comportement te convient, tu peux ne pas
redéfinir __reduce__()
.
10.3 Lecture et écriture de l'état
Méthodes __getstate__()
et
__setstate__()
Ces méthodes sont utilisées pour gérer l'état d'un objet pendant la sérialisation et la désérialisation.
-
__getstate__()
: Retourne l'état de l'objet, qui doit être sérialisé. -
__setstate__(self, state)
: Restaure l'objet à partir de l'état.
Exemple :
Disons que nous voulons sauvegarder non pas tous les champs de l'objet, mais en exclure
certains. Pour ce faire, dans la méthode __getstate__()
, il faut :
-
Copier l'état actuel de l'objet (défini par le champ de service
__dict__
) dans une variable séparée — le dictionnairestate
. - Supprimer de celle-ci tous les champs qui ne doivent pas être sérialisés.
- Retourner l'objet obtenu en tant que résultat de la fonction
__getstate__()
.
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'] # Exclusion de l'état interne
return state
def __setstate__(self, state):
self.__dict__.update(state)
self.internal_state = "restored internal" # Restauration de l'état interne
def __repr__(self):
return f"CustomClass(value={self.value}, internal_state={self.internal_state})"
# Création de l'objet
obj = CustomClass(42)
print("Objet original :", obj)
# Sérialisation de l'objet
serialized_obj = pickle.dumps(obj)
print("Objet sérialisé :", serialized_obj)
# Désérialisation de l'objet
deserialized_obj = pickle.loads(serialized_obj)
print("Objet désérialisé :", deserialized_obj)
Lors de la désérialisation, dans la fonction __setstate__()
, nous faisons deux choses :
-
Nous mettons à jour l'état actuel de l'objet à l'aide de la méthode
update()
. -
Le champ
internal_state
(et les autres champs non sérialisés) reçoivent de nouvelles valeurs.
GO TO FULL VERSION