Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > pickle and instancemethod objects

Reply
Thread Tools

pickle and instancemethod objects

 
 
Steven Bethard
Guest
Posts: n/a
 
      09-13-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
 
Reply With Quote
 
 
 
 
=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
Guest
Posts: n/a
 
      09-13-2006
Steven Bethard schrieb:
> Does this approach seem sound? Am I going to run into some weird
> problems doing it this way?


It's good, but I think rebuilding the object through
new.instancemethod should be even better.

py> class A:
.... def f(self)rint "A"
....
py> class B(A):
.... def f(self)rint "B"
....
py> b=B()
py> b.f
<bound method B.f of <__main__.B instance at 0xa7d728cc>>
py> x = new.instancemethod(A.__dict__['f'], b, A)
py> x
<bound method A.f of <__main__.B instance at 0xa7d728cc>>
py> x()
A
py> b.f()
B
py> x.im_func.__name__,x.im_class,x.im_self
('f', <class __main__.A at 0xa7d7002c>, <__main__.B instance at 0xa7d728cc>)

On unpickling x, you'ld get x.(B.f), not x.(A.f) with your
approach.

Not sure it matters much.

Regards,
Martin
 
Reply With Quote
 
 
 
 
Steven Bethard
Guest
Posts: n/a
 
      09-13-2006
Martin v. L÷wis wrote:
> Steven Bethard schrieb:
>> Does this approach seem sound? Am I going to run into some weird
>> problems doing it this way?

>
> It's good, but I think rebuilding the object through
> new.instancemethod should be even better.
>
> py> class A:
> ... def f(self)rint "A"
> ...
> py> class B(A):
> ... def f(self)rint "B"
> ...
> py> b=B()
> py> b.f
> <bound method B.f of <__main__.B instance at 0xa7d728cc>>
> py> x = new.instancemethod(A.__dict__['f'], b, A)
> py> x
> <bound method A.f of <__main__.B instance at 0xa7d728cc>>
> py> x()
> A
> py> b.f()
> B
> py> x.im_func.__name__,x.im_class,x.im_self
> ('f', <class __main__.A at 0xa7d7002c>, <__main__.B instance at 0xa7d728cc>)
>
> On unpickling x, you'ld get x.(B.f), not x.(A.f) with your
> approach.
>
> Not sure it matters much.


Probably doesn't matter for my particular use, but it certainly wouldn't
hurt to do it the careful way. Thanks.

Is new.instancemethod basically equivalent to calling __get__? That is,
would the following two unpickle_instancemethod functions do the same thing?

def unpickle_instancemethod(func_name, cls, obj):
return cls.__dict__[func_name].__get__(obj, cls)

def unpickle_instancemethod(func_name, cls, obj):
return new.instancemethod(cls.__dict__[func_name], obj, cls)

Thanks again,

STeVe
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pickle error: can't pickle instancemethod objects Michele Simionato Python 2 05-23-2008 08:29 AM
can't pickle instancemethod objects Jim Lewis Python 6 07-09-2006 09:07 PM
a pickle's pickle temposs@gmail.com Python 4 08-02-2005 07:20 PM
'class' argument optional for new.instancemethod? Martin Miller Python 1 03-12-2005 01:31 AM
Why instancemethod when I can add functions to classes outside class body? Rim Python 7 07-28-2003 03:30 PM



Advertisments