pickle and instancemethod objects

Steven Bethard steven.bethard at gmail.com
Wed Sep 13 11:08:45 EDT 2006


I'd like to be able to pickle instancemethod objects mainly because I 
want to be able to delay a call like ``foo(spam, badger)`` by dumping 
``foo``, ``spam`` and ``badger`` to disk and loading them again later. 
Sometimes the callable ``foo`` is actually a bound method, e.g. 
``bar.baz``, but in such cases, pickle doesn't work by default because 
it doesn't know how to pickle/unpickle instancemethod objects.

I was thinking of doing something like::

 >>> def pickle_instancemethod(method):
...     func_name = method.im_func.__name__
...     cls = method.im_class
...     obj = method.im_self
...     return unpickle_instancemethod, (func_name, cls, obj)
...
 >>> def unpickle_instancemethod(func_name, cls, obj):
...     if obj is None:
...         return getattr(cls, func_name)
...     else:
...         return getattr(obj, func_name)
...
 >>> class C(object):
...     def __init__(self, foo, bar):
...         self.foo = foo
...         self.bar = bar
...     def baz(self):
...         return self.foo, self.bar
...
 >>> copy_reg.pickle(type(C.baz),
...                 pickle_instancemethod,
...                 unpickle_instancemethod)

This seems to basically do the right thing on the few simple things I've 
tried::

 >>> c = C(42, 'badger')
 >>> new_c_baz = pickle.loads(pickle.dumps(c.baz))
 >>> new_c_baz()
(42, 'badger')
 >>> new_C_baz = pickle.loads(pickle.dumps(C.baz))
 >>> new_C_baz(C('eki', 'fekang'))
('eki', 'fekang')

Does this approach seem sound?  Am I going to run into some weird 
problems doing it this way?

Thanks,

STeVe



More information about the Python-list mailing list