How to better pickle an extension type

Alex Martelli aleax at mac.com
Tue Apr 17 00:54:37 EDT 2007


dgdev <dgdev3141 at yahoo.com> wrote:

> I would like to pickle an extension type (written in pyrex).  I have
> it working thus far by defining three methods:
> 
> class C:
>       # for pickling
>       __getstate__(self):
>               ... # make 'state_obj'
>               return state_obj
> 
>       __reduce__(self):
>               return C,(args,to,__init__),me.__getstate__()
> 
>       # for unpickling
>       __setstate__(self,state_obj):
>               self.x=state_obj.x
>               ...
> 
> 
> This gets the class pickling and unpickling.
> 
> However, I'd like to not specify arguments for __init__ (as I do now
> in __reduce__), and so not have __init__ invoked during unpickling.
> 
> I would like to have the pickling machinery somehow create an
> uninitialized object, and then call its __setstate__, where I can re-
> create it from 'state_obj'.
> 
> Is there a kosher way to do so, that is without me having to have a
> special mode in the constructor for when the object is being created
> by the unpickler?

I don't understand why you have a problem -- __init__ is NOT called by
default upon loading an object w/__setstate__.  Witness:

>>> class C(object):
...   def __init__(self, *a): print 'init', a
...   def __getstate__(self): print 'gs'; return {}
...   def __setstate__(self, *a): print 'ss', a
... 
>>> c = C()              
init ()
>>> s = cPickle.dumps(c, 2)
gs
>>> s
'\x80\x02c__main__\nC\nq\x01)\x81q\x02}b.'
>>> z = cPickle.loads(s)
ss ({},)


Perhaps you're not using protocol 2?  You should be...


Alex



More information about the Python-list mailing list