How to better pickle an extension type
dgdev
dgdev3141 at yahoo.com
Wed Apr 18 10:13:02 EDT 2007
Thanks for your replies.
The code I showed above was pyrex code, not python code. You are
correct that python objects do not require .__reduce__() to be
picklable, but apparently c extension types do (makes sense, they must
be more opaque to the python machinery).
I'll try the .__newobj__(), see if I can get it to do what I want...
On Apr 17, 2:50 am, Ziga Seilnacht <ziga.seilna... at gmail.com> wrote:
> dgdev wrote:
> > I would like topicklean extension type (written inpyrex). 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?
>
> Why are you overwriting the __reduce__() method? The default
> object.__reduce__() method, inherited by all new style classes,
> already does what you want. If you really must overwrite it, and
> you don't want __init__() to get called, then you should return a
> reconstructor named __newobj__() as the first item of reduce
> tuple. Something like this:
>
> >>> def __newobj__(cls, *args):
>
> ... return cls.__new__(cls, *args)
> ...>>> class C(object):
>
> ... def __init__(self):
> ... print "I shouldn't be called at reconstruction"
> ... def __reduce__(self):
> ... try:
> ... getnewargs = self.__getnewargs__
> ... except AttributeError:
> ... newargs = (self.__class__,)
> ... else:
> ... newargs = (self.__class__,) + getnewargs()
> ... try:
> ... getstate = self.__getstate__
> ... except AttributeError:
> ... # this ignores __slots__ complications
> ... state = self.__dict__
> ... else:
> ... state = getstate()
> ... # this ignores list and dict subclasses
> ... return __newobj__, newargs, state
> ...>>> c = C()
>
> I shouldn't be called at reconstruction>>> importpickle
> >>> for proto in range(3):
>
> ... assert isinstance(pickle.loads(pickle.dumps(c, proto)), C)
> ...
>
>
>
> Ziga
More information about the Python-list
mailing list