6

I have a simple class to just store data that's associated to a circuit board like this :

class boardClass():

    def __init__(self,boardName):
        self.__name=boardName
        self.__boardMappings= {boardName:{
                                  'FastMode':
                                  {'CPU_A':{'mipi':[], 'gpen':[]},
                                   'CPU_B':{'mipi':[], 'gpen':[]}

                                  'SlowMode':
                                  {'CPU_A':{'mipi':[], 'gpen':[]},
                                   'CPU_B':{'mipi':[], 'gpen':[]}                                   
                                  }
                                 }                       
                               }


    def setMode(self, board, mode, cpu,mipi,gpen):
        self.__boardMappings[board][mode][cpu]['mipi']=mipi
        self.__boardMappings[board][mode][cpu]['gpen']=gpen

    def getName(self):
        return self.__name

I use pickle in another class to store the boardClass data in file and later read them:

def onSave(self,boardName):
        board=boardClass.boardClass(boardName)
        name=boardName+".brd"
        file=open(name,"wb")            
        pickle.dump(board,file)                        
        loadedBoard= pickle.load( open( file, "rb" ))            
        print "Loaded board name is : ",loadedBoard.getName()

When I call onSave() method to pickle the boardClass, it gives several errors ending with this at end:

File "C:\Python27\lib\copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle PySwigObject objects

This boardClass is very simple container. Why can't it be pickled?

  • 2
    [PEP 8](http://www.python.org/dev/peps/pep-0008/) would like you to name your class `Board` (not `BoardClass` as you know it's a class), `setMode` `set_mode`, etc. Also things like spaces after colons in a dict literal and spaces around the `=` in assignment. Finally, you should do `class Board(object)` to make it a new-style class. – Chris Morgan Apr 25 '12 at 00:07
  • 4
    Your code isn't making sense as it stands. In what class is `onSave` defined? Where is `boardName` defined in `onSave`? Where is the `PySwigObject` coming from (you're clearly doing more in the board than you've shown)? – Chris Morgan Apr 25 '12 at 00:08
  • Chris , it doesn't matter where onSave() is defined its in another class and will be called when user wants to save the board.(or code to pickle it) I don't know where PySwigObject is coming from I don't have that in my code and for pickle part this is all the code. Also doing class Board(object) didn't solve anything. –  Apr 25 '12 at 01:32
  • Well, with the code as you've got it, it will work. (Try it.) You've got other significant code somewhere which you haven't shown. My first comment was (almost) purely about stylistic matters; apart from the new-style class bit (which will fix some strange behaviour in obscure places), it won't change any functionality. – Chris Morgan Apr 25 '12 at 01:33
  • being pickleable is part of the "strange behaviors" fixed by having a new style class. – jsbueno Apr 25 '12 at 03:06
  • @jsbueno: not true; old-style classes can be pickled. This is something to do with his object including a SWIG object in it. – Chris Morgan Apr 25 '12 at 05:06
  • has setMode been called? if mipi or gpen include objects which have a PySwigObject in them, then the BoardClass object won't be picklable. – Jonathan Villemaire-Krajden Jul 10 '14 at 03:57

4 Answers4

6

Instead of inherting from "nothing", inherit from "object" - this way your class will no longer be a "Class Instance" - it will be a proper instance of a new-style class, and as such, be "pickeable"

In other words, just try changing this line:

class boardClass():

to this:

class boardClass(object):

update: This answer is from Python 2 era - and explicitly inheritng from object was needed there. In Python 3 it is no longer the case: inheritance from object is automatic, and if pickle is failing it is for some other reason.

jsbueno
  • 99,910
  • 10
  • 151
  • 209
1

If you really want to keep your object such that it doesn't take "object" in the argument, you could use a serializer like dill or cloudpickle that can serialize both old and new-style class instances (for both python 2.x and 3.x syntaxes).

Mike McKerns
  • 33,715
  • 8
  • 119
  • 139
1

You can't pickle PySwigObjects, However there's a workaround here: Pickling objects

Community
  • 1
  • 1
1

This is an old question, and the name is quite generic, so if you see it now you probably want to set __getstate__ and __setstate__ of your class so pickle would know how to dump and load you defined class.

See examples here.

If your class is simple (e.g. only have ints and strings as members and any method) it should be pickalable automatically.

borgr
  • 20,175
  • 6
  • 25
  • 35