147 votes

Exemple simple d'utilisation de __setstate__ et __getstate__

Je ne sais pas ce que font les méthodes __setstate__ __getstate__ et %-% + %-%, alors aidez-moi avec un exemple simple.

117voto

BrainCore Points 1936

Voici un exemple très simple pour Python qui devrait compléter les docs pickle.

class Foo(object):
  def __init__(self, val=2):
     self.val = val
  def __getstate__(self):
     print("I'm being pickled")
     self.val *= 2
     return self.__dict__
  def __setstate__(self, d):
     print("I'm being unpickled with these values: " + repr(d))
     self.__dict__ = d
     self.val *= 3

import pickle
f = Foo()
f_data = pickle.dumps(f)
f_new = pickle.loads(f_data)

18voto

Pär Wieslander Points 11258

Ces procédés sont utilisés pour contrôler la manière dont les objets sont décapés et décapés par le module de décapage. Ceci est généralement géré automatiquement, donc à moins que vous n'ayez besoin de remplacer la façon dont une classe est décapée ou décapée, vous ne devriez pas avoir à vous en soucier.

6voto

Azmisov Points 1229

Une clarification de la réponse de @ BrainCore. En pratique, vous ne voudrez probablement pas modifier self l'intérieur de __getstate__. Au lieu de cela, construisez un nouvel objet qui sera décapé, laissant l'original inchangé pour une utilisation ultérieure. Voici à quoi cela ressemblerait :

import pickle

class Foo:
    def __init__(self, x:int=2, y:int=3):
        self.x = x
        self.y = y
        self.z = x*y

    def __getstate__(self):
        # Create a copy of __dict__ to modify values and return;
        # you could also construct a new dict (or other object) manually
        out = self.__dict__.copy()
        out["x"] *= 3
        out["y"] *= 10
        # You can remove attributes, but note they will not get set with
        # some default value in __setstate__ automatically; you would need
        # to write a custom __setstate__ method yourself; this might be
        # useful if you have unpicklable objects that need removing, or perhaps
        # an external resource that can be reloaded in __setstate__ instead of
        # pickling inside the stream
        del out["z"]
        return out

    # The default __setstate__ will update Foo's __dict__;
    # so no need for a custom implementation here if __getstate__ returns a dict;
    # Be aware that __init__ is not called by default; Foo.__new__ gets called,
    # and the empty object is modified by __setstate__

f = Foo()
f_str = pickle.dumps(f)
f2 = pickle.loads(f_str)

print("Pre-pickle:", f.x, f.y, hasattr(f,"z"))
print("Post-pickle:", f2.x, f2.y, hasattr(f2,"z"))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X