Python Language Personnaliser les données marinées


Exemple

Certaines données ne peuvent pas être décapées. Les autres données ne doivent pas être décapées pour d'autres raisons.

Ce qui sera décapé peut être défini dans la méthode __getstate__ . Cette méthode doit renvoyer quelque chose qui est picklable.

Sur le côté opposé, __setstate__ : il recevra ce que __getstate__ créé et doit initialiser l'objet.

class A(object):
    def __init__(self, important_data):
        self.important_data = important_data
        
        # Add data which cannot be pickled:
        self.func = lambda: 7
        
        # Add data which should never be pickled, because it expires quickly:
        self.is_up_to_date = False
    
    def __getstate__(self):
        return [self.important_data] # only this is needed
    
    def __setstate__(self, state):
        self.important_data = state[0]
        
        self.func = lambda: 7  # just some hard-coded unpicklable function
        
        self.is_up_to_date = False  # even if it was before pickling

Maintenant, cela peut être fait:

>>> a1 = A('very important')
>>>
>>> s = pickle.dumps(a1)  # calls a1.__getstate__()
>>>
>>> a2 = pickle.loads(s)  # calls a1.__setstate__(['very important'])
>>> a2
<__main__.A object at 0x0000000002742470>
>>> a2.important_data
'very important'
>>> a2.func()
7

L'implémentation ici affiche une liste avec une valeur: [self.important_data] . C'était juste un exemple, __getstate__ aurait pu retourner tout ce qui est picklable, tant que __setstate__ sait comment oppoisite. Une bonne alternative est un dictionnaire de toutes les valeurs: {'important_data': self.important_data} .

Le constructeur n'est pas appelé! Notez que dans l'exemple précédent, l'instance a2 été créée dans pickle.loads sans jamais appeler A.__init__ , donc A.__setstate__ devait initialiser tout ce que __init__ aurait initialisé s'il était appelé.