Je veux que ma classe implémente les fonctions Save and Load qui font simplement un pickle de la classe. Mais apparemment, vous ne pouvez pas utiliser le "soi" de la manière ci-dessous. Comment peux-tu faire ça?
self = cPickle.load(f)
cPickle.dump(self,f,2)
C'est ce que j'ai fini par faire. Mise à jour du __dict__
signifie que nous conservons toutes les nouvelles variables de membre que j'ajoute à la classe et que nous mettons simplement à jour celles qui étaient là lorsque l'objet a été pickle pour la dernière fois. Cela semble le plus simple tout en conservant le code de sauvegarde et de chargement à l'intérieur de la classe elle-même, donc appeler du code ne fait qu'un object.save ().
def load(self):
f = open(self.filename, 'rb')
tmp_dict = cPickle.load(f)
f.close()
self.__dict__.update(tmp_dict)
def save(self):
f = open(self.filename, 'wb')
cPickle.dump(self.__dict__, f, 2)
f.close()
La partie de vidage devrait fonctionner comme vous l'avez suggéré. pour la partie chargement, vous pouvez définir un @ classmethod qui charge une instance à partir d'un fichier donné et la renvoie.
@classmethod
def loader(cls,f):
return cPickle.load(f)
alors l'appelant ferait quelque chose comme:
class_instance = ClassName.loader(f)
Si vous voulez que votre classe se mette à jour elle-même à partir d'un cornichon enregistré… vous devez à peu près utiliser __dict__.update
, comme vous l'avez fait dans votre propre réponse. C'est un peu comme un chat poursuivant sa queue, cependant… comme vous demandez à l'instance de se "réinitialiser" essentiellement avec l'état antérieur.
Il y a un léger ajustement à votre réponse. Vous pouvez en fait pickle self
.
>>> import dill
>>> class Thing(object):
... def save(self):
... return dill.dumps(self)
... def load(self, obj):
... self.__dict__.update(dill.loads(obj).__dict__)
...
>>> t = Thing()
>>> t.x = 1
>>> _t = t.save()
>>> t.x = 2
>>> t.x
2
>>> t.load(_t)
>>> t.x
1
J'ai utilisé loads
et dumps
au lieu de load
et dump
parce que je voulais que le cornichon soit sauvegardé dans une chaîne. L'utilisation de load
et dump
dans un fichier fonctionne également. Et, en fait, je peux utiliser dill
pour ramasser une instance de classe dans un fichier, pour une utilisation ultérieure… même si la classe est définie de manière interactive. Continuant d'en haut ...
>>> with open('self.pik', 'w') as f:
... dill.dump(t, f)
...
>>>
puis arrêt et redémarrage ...
Python 2.7.10 (default, May 25 2015, 13:16:30)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> with open('self.pik', 'r') as f:
... t = dill.load(f)
...
>>> t.x
1
>>> print dill.source.getsource(t.__class__)
class Thing(object):
def save(self):
return dill.dumps(self)
def load(self, obj):
self.__dict__.update(dill.loads(obj).__dict__)
>>>
J'utilise dill
, qui est disponible ici: https://github.com/uqfoundation
Il y a un exemple de comment pickle une instance ici, dans la documentation . (Recherchez l'exemple "TextReader"). L'idée est de définir __getstate__
et __setstate__
, qui vous permettent de définir quelles données doivent être picklées et comment utiliser ces données pour ré-instancier l'objet.