How To Remove Instancemethod Objects, For The Sake Of Pickle, Without Modifying The Original Class
I want to persistantly hold on to an object from reverend.thomas.Bayes. Of course, if I try to pickle one of these classes directly, I get: TypeError: can't pickle instancemethod o
Solution 1:
The better solution would be for you to add a __getstate__
method onto the Bayes
class (with accompanying __setstate__
):
import types
from reverend.thomas import Bayes
def Bayes__getstate__(self):
state = {}
for attr, value in self.__dict__.iteritems():
if not isinstance(value, types.MethodType):
state[attr] = value
elif attr == 'combiner' and value.__name__ == 'robinson':
# by default, self.combiner is set to self.robinson
state['combiner'] = None
return state
def Bayes__setstate__(self, state):
self.__dict__.update(state)
# support the default combiner (an instance method):
if 'combiner' in state and state['combiner'] is None:
self.combiner = self.robinson
Bayes.__getstate__ = Bayes__getstate__
Bayes.__setstate__ = Bayes__setstate__
Now the Bayes
class can always be pickled and unpickled without additional processing.
I do see that the class has a self.cache = {}
mapping; perhaps that should be excluded when pickling? Ignore it in __getstate__
and call self.buildCache()
in __setstate__
if that is the case.
Solution 2:
k
is a key i.e. the attribute/method name. You need to test the attribute itself:
if type(dic[k]) == types.MethodType:
^~~~~~ here
I'd prefer using a comprehension; you should also be using isinstance
:
dic = dict((k, v) for k, v in bayes_obj.__dict__
if not isinstance(v, types.MethodType))
Solution 3:
This sounds like getting a square peg to fit a round hole. How about using pickle to pickle the arguments, and unpickle to reconstruct the reverand.Thomas.Bayes
object?
>>> from collections import namedtuple
>>> ArgList = namedtuple('your', 'arguments', 'for', 'the', 'reverand')
>>> def pickle_rtb(n):
... return pickle.dumps(ArgList(*n.args))
...
>>> def unpickle_rtb(s):
... return reverand.Thomas.Bayes(*pickle.loads(s))
...
>>> s = pickle_rtb(reverand.Thomas.Bayes(1, 2, 3, 4, 5)) # note arguments are a guess
>>> rtb = unpickle_norm(s)
Inspired by this SO question.
Post a Comment for "How To Remove Instancemethod Objects, For The Sake Of Pickle, Without Modifying The Original Class"