Why can't pickle dump this instance?
__peter__ at web.de
Fri Aug 13 14:34:29 CEST 2004
Jane Austine wrote:
> class A:
> def __init__(self,tick):
> if tick:
> def bar(self):
> print 'bar'
> def bur(self):
> print 'bur'
> import pickle
> running this script results in "TypeError: can't pickle function objects"
> Why does this happen? and what can I do?
By default pickle bypasses the __init__() method completely, it just saves
class name and the instance's __dict__. In your case __dict__ happens to
contain a bound method which cannot be pickled. I don't know why, maybe the
general case where the instance the method is bound to could be a different
object would get too messy.
The normal way to manipulate the state to be pickled/unpickled is to
implement the __getstate__()/__setstate__() pair, but in your case it is
easier to trigger invocation of __init__() by generating the appropriate
argument list via __getinitargs__().
def __init__(self, tick):
self.foo = self.bar
self.foo = self.bur
# copy the __dict__ so that further changes
# do not affect the current instance
d = dict(self.__dict__)
# remove the closure that cannot be pickled
# return state to be pickled
tick = self.foo == self.bar
# return argument tuple for __init__()
# all items must be pickleable
if __name__ == "__main__":
# test it
for tick in [False, True]:
print "\ntick =", tick
a = A(tick)
s = pickle.dumps(a)
b = pickle.loads(s)
More information about the Python-list