pickling question

Gary Robinson garyrob at me.com
Wed Sep 2 22:51:29 CEST 2009


Many thanks for the responses I've received here to my question (below).

After reading the responses, I understand what the problem is much better. In addition to the solutions mentioned in the responses, now that I understand the problem I'll offer up my own solution. The following is an executable script named pick1.py:

===============
import pickle

class A(object):

    def __init__(self, x):
        self.x = x
        
def writePickle():
    import pick1
    a5 = pick1.A(5)
    f = open('pick1.pickle', 'wb')
    pickle.dump(a5, f)
    f.close()
    
writePickle() # The dumped pickle can be read by any other script.
================

That is, we need to do the pickling in a context where the module name for the class is "pick1" rather than "__main__". The example above allows us to do that without changing __name__ or doing anything else of that nature.

Thanks again!
Gary



> When you define a class in a script, and then pickle instances of 
> that class in the same script and store them to disk, you can't load 
> that pickle in another script. At least not the straightforward way 
> [pickle.load(file('somefile.pickle'))]. If you try it, you get an 
> AttributeError during the unpickling operation.
> 
> There is no problem, of course, if the class is defined in a module 
> which is imported by the pickling script. 
> pickle.load(file('somefile.pickle')) then works.
> 
> Rather than provide specific examples here, there's a blog post from 
> 2005 that discusses this issue in depth and presents the problem very 
> well: http://stefaanlippens.net/pickleproblem. (I tested in Python 
> 2.6 yesterday and the same issue persists.)
> 
> Questions:
> 
> 1) Does this have to be the case, or is it a design problem with 
> pickles that should be remedied?
> 
> 2) Is there an easier way around it than moving the class definition 
> to a separate module? The blog post I point to above suggests putting 
> "__module__ = os.path.splitext(os.path.basename(__file__))[0]" into 
> the class definiton, but that's not working in my testing because 
> when I do that, the pickling operation fails. Is there something else 
> that can be done?
> 
> This is obviously not a huge problem. Substantial classes should 
> usually be defined in a separate module anyway. But sometimes it 
> makes sense for a script to define a really simple, small class to 
> hold some data, and needing to create a separate module just to 
> contain such a class can be a little annoying.
-- 

Gary Robinson
CTO
Emergent Music, LLC
personal email: garyrob at me.com
work email: grobinson at flyfi.com
Company: http://www.flyfi.com
Blog:    http://www.garyrobinson.net



More information about the Python-list mailing list