how to use copy_reg/pickle (was Re: how to pickle unpicklable objects)

Guy Lateur guy.lateur at b-b.be
Mon Sep 26 11:57:30 CEST 2005


Thanks for the swift reply, Hans, and sorry for my delayed reaction.

I've been looking at the copy_reg module, but I can't seem to get it to 
work.

wx.Font has a method called GetNativeFontInfo(), which returns a string 
description of the font. Here's what I had hoped would have worked.

[code]
def reducef(objf):
    return str(objf.GetNativeFontInfo())
def constrf(strf):
    rv = wx.Font()
    rv.SetNativeFontInfo(wx.String(strf))
    return rv
copy_reg.pickle(wx.Font, reducef, constrf)
valf = wx.Font(10, wx.NORMAL, wx.NORMAL, wx.NORMAL, False, 'Arial')
rvf = pickle.dumps(valf)
[/code]

Unfortunately, this raises the exception:
pickle.PicklingError: Can't pickle <wx._gdi.Font; proxy of C++ wxFont 
instance at _c8bb6101_p_wxFont>: it's not found as 
wx._gdi.0;-13;0;0;0;400;0;0;0;1;0;0;0;32;Arial

Like I said, this is how I hoped it would work. I've read in the pickle docs 
you should return the name of a global var containing the value to be 
pickled as usual. I've tried this (without really understanding it), too, 
but without any success.

Could somebody please help me to modify this example so that it works?

Best regards,
g




"Hans Georg Krauthaeuser" <hgk at et.uni-magdeburg.de> schreef in bericht 
news:dh10st$7kv$1 at fuerst.cs.uni-magdeburg.de...
> Guy Lateur schrieb:
>> Hi all,
>>
>> I've been writing an application containing a lot of settings which can 
>> be
>> changed by the user. I'm using wx.Config to read/write these settings (to
>> the windows registry). This means I can only store strings, ints and 
>> floats.
>>
>> However, it would be very convenient if I could also store more general
>> objects. It seems to work for wx.Colour, but not for wx.Font. It raises a
>> "TypeError: can't pickle PySwigObject objects".
>
> The object is wrapped by SWIG. So, python can not know anything about it
> and the object can not be pickled.
>
> As far as I see, there are two possibilities
> - define __getstate__ and __setstate__ in the c/c++-source or the .i
> file (used by swig). This is only possible if the source is available
> - use copy_reg (http://docs.python.org/lib/module-copyreg.html) to
> register a 'reduce' function (I never used that).
>
> I use the first option in the .i-File for a wrapped c++-class like this:
>
> %extend UMDMResult {
> %insert("python") %{
> def __getstate__(self):
>    return (self.v,self.u,self.l,self.unit,self.Z0,self.Eta0,self.t)
> def __setstate__(self,tup):
>    self.this = _umddevice.new_UMDMResult(tup[0],tup[1],tup[2],tup[3])
>    self.thisown=1
>    (self.Z0,self.Eta0,self.t)=[i for i in tup[4:]]
> %}
> }
>
> regards
> Hans Georg Krauthaeuser 





More information about the Python-list mailing list