[wxPython] saving instance data to file using pickle/marshal not working

Hi All:

Im having trouble finding a function to save my data structures. Ive had
a look at pickle, cPickle, marshal and shelve, NONE of which seem to be
useful. ie:

Traceback (most recent call last):
  File "./mainScript.py", line 2400, in OnFileSaveAs
    self.OnFileSave(None)
  File "./mainScript.py", line 2379, in OnFileSave
    self.OnSaveContents()
  File "./mainScript.py", line 2418, in OnSaveContents
    pickleData = cPickle.dumps(canvasData)
cPickle.UnpickleableError: Cannot pickle <type 'instance method'> objects

and

Traceback (most recent call last):
  File "./mainScript.py", line 2401, in OnFileSaveAs
    self.OnFileSave(None)
  File "./mainScript.py", line 2380, in OnFileSave
    self.OnSaveContents()
  File "./mainScript.py", line 2419, in OnSaveContents
    marshalData = marshal.dumps(canvasData)
ValueError: unmarshallable object

I have a canvas(wxScrolledWindow) contaning shapes(myClass) and
lines(myClass). The shape instances contain a list[] of pointers to
lines, and the line instances conatin a list[] of pointers to shapes(so
the lines know what shapes they connect). I want to save the
configuration(shapes/lines) to a file, to allow reloading of a saved file.

I understand that pickle/marshal etc can only store simple data like
dictionaries{}, lists[] etc; NOT INSTANCES. <please excuse my ignorance>
So how do I write to a file the entire shape/line configuration containing
the nessissary links between the instances of shapes and lines?
Do I have to convert the entire configuration to say a dictionary{}, and
just pickle that dictionary? I need to preserve the links between shapes
and lines currently stored as lists[] of pointers to instances.

Thanks,
BenG.

···

_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com

First, use cPickle, it's slower than marshal, but it's far more widely used and robust in terms of what it can save.

Second, what's almost certainly tripping you up is that you've stored a reference to one of your window's methods somewhere in your data structure. When pickle gets to that, it doesn't know how to store it (hence the error messages). Unfortunately, pickle isn't intelligent enough to try to tell you _what_ object is causing the problem, so you have to figure it out with some sluthing through.

Here's your basic data-model...

from basicproperty import common, basic, propertied
class Shape( propertied.Propertied ):
  lines = common.TypedListProperty(
    "lines", "Lines that draw me",
    familiarName = "Lines",
    acceptableTypes = ( "mymodule.Lines", ),
  )
class Line( propertied.Propertied ):
  coordinates = common.ListProperty(
    "coordinates", "Points to draw (connected), list of tuples",
    familiarName = "Coordinates",
  )
  shape = basic.BasicProperty(
    "shape", "Link back to the shape object",
    familiarName = "Shape",
    defaultValue = None,
  )

Now, as long as _only_ those properties are specified (which if I'm reading correctly, is supposed to be true), then your data should be easily pickleable (pickle can handle mutually referencing objects, BTW).

The problem is that you've likely got a reference to myPanel.Draw or something similar stored in one of those objects (or even a pointer to myPanel, though that's less likely the cause of this particular error I would think). So, what you're looking for is some place in your app where you've broken the model|view pattern by storing view-specific info in your data-model.

You can scan through your model objects basically checking that all objects have only those properties they are supposed to have. Anything which isn't a defined property is a problem.

Alternately, if you feel comfortable with debuggers, you can use pickle instead of cPickle for testing and alter the code so that you are dropped to a debugger (e.g. pdb) when the error occurs and you can see what the object causing the problem is.

HTH,
Mike
    
Ben Gerblich wrote:

···

Hi All:

Im having trouble finding a function to save my data structures. Ive had
a look at pickle, cPickle, marshal and shelve, NONE of which seem to be
useful. ie:

Traceback (most recent call last):
File "./mainScript.py", line 2400, in OnFileSaveAs
   self.OnFileSave(None)
File "./mainScript.py", line 2379, in OnFileSave
   self.OnSaveContents()
File "./mainScript.py", line 2418, in OnSaveContents
   pickleData = cPickle.dumps(canvasData)
cPickle.UnpickleableError: Cannot pickle <type 'instance method'> objects

and

Traceback (most recent call last):
File "./mainScript.py", line 2401, in OnFileSaveAs
   self.OnFileSave(None)
File "./mainScript.py", line 2380, in OnFileSave
   self.OnSaveContents()
File "./mainScript.py", line 2419, in OnSaveContents
   marshalData = marshal.dumps(canvasData)
ValueError: unmarshallable object

I have a canvas(wxScrolledWindow) contaning shapes(myClass) and
lines(myClass). The shape instances contain a list of pointers to
lines, and the line instances conatin a list of pointers to shapes(so
the lines know what shapes they connect). I want to save the
configuration(shapes/lines) to a file, to allow reloading of a saved file.

I understand that pickle/marshal etc can only store simple data like
dictionaries{}, lists etc; NOT INSTANCES. <please excuse my ignorance>
So how do I write to a file the entire shape/line configuration containing
the nessissary links between the instances of shapes and lines?
Do I have to convert the entire configuration to say a dictionary{}, and
just pickle that dictionary? I need to preserve the links between shapes
and lines currently stored as lists of pointers to instances.

Thanks,
BenG.

_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwindows.org
http://lists.wxwindows.org/mailman/listinfo/wxpython-users

--
_______________________________________
   Mike C. Fletcher
   Designer, VR Plumber, Coder
   http://members.rogers.com/mcfletch/