Je ne sais pas ce que font les méthodes __setstate__
__getstate__
et %-% + %-%, alors aidez-moi avec un exemple simple.
Réponses
Trop de publicités?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)
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.
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"))