473,385 Members | 1,357 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Moving class used in pickle

I have a class derived from string that is used in a pickle. In the new
version of my program, I moved the module containing the definition of the
class. Now the unpickle fails because it doesn't find the module. I was
thinking that I could make the unpickle work by putting a copy of the
module in the original location and then redefine the class by sticking a
__setstate__ in the class thusly:

def __setstate__(self, state):
self.__dict__.update(state)
self.__class__ = NewClassName

My plan was to specify the new location of the module in NewClassName.
However, when I do this I get the message "'class' object layout differs
from 'class'". I don't think that they do as the new module is a copy of
the old one. I suspect that I am not allowed to make the class assignment
because my class is derived from string. What is the best way to update
the pickle? The only thought I have is to read all the data with the old
class module, store the data in some nonpickle format, and then, with
another program, read the nonpickle-format file and rewrite the pickle with
the class module in the new location.
--
Jeffrey Barish

May 15 '07 #1
3 2277
Jeffrey Barish <je*********@earthlink.netwrites:
I have a class derived from string that is used in a pickle. In the new
version of my program, I moved the module containing the definition of the
class. Now the unpickle fails because it doesn't find the module. I was
thinking that I could make the unpickle work by putting a copy of the
module in the original location and then redefine the class by sticking a
__setstate__ in the class thusly:

def __setstate__(self, state):
self.__dict__.update(state)
self.__class__ = NewClassName

My plan was to specify the new location of the module in NewClassName.
However, when I do this I get the message "'class' object layout differs
from 'class'". I don't think that they do as the new module is a copy of
the old one. I suspect that I am not allowed to make the class assignment
because my class is derived from string. What is the best way to update
the pickle? The only thought I have is to read all the data with the old
class module, store the data in some nonpickle format, and then, with
another program, read the nonpickle-format file and rewrite the pickle with
the class module in the new location.
You can fiddle with the file class used reading the pickled file. I.e.
the "read()" method could replace each instance of "foo.myclass" by
"greatnewmodule.mynewclass" could bring you back in the game.

Porting some applications of my from 32 to 64 bit i discovered that my
Numeric int arrays really had to be int32. So i opened the (binary)
pickled files and replaced the occurences of "'l'" by "'i'". Later we
replaced Numeric by numpy. I used the editor approach again to replace
"Numeric" string by "numpy" or "numpy.oldnumeric". A collegue of mine
wrote a small reader class implementing the approach working on the
input stream.

Regards
Berthold
--
May 21 '07 #2
Jeffrey Barish wrote:
I have a class derived from string that is used in a pickle. In the new
version of my program, I moved the module containing the definition of the
class. Now the unpickle fails because it doesn't find the module. I was
thinking that I could make the unpickle work by putting a copy of the
module in the original location and then redefine the class by sticking a
__setstate__ in the class thusly:

def __setstate__(self, state):
self.__dict__.update(state)
self.__class__ = NewClassName

My plan was to specify the new location of the module in NewClassName.
However, when I do this I get the message "'class' object layout differs
from 'class'". I don't think that they do as the new module is a copy of
the old one. I suspect that I am not allowed to make the class assignment
because my class is derived from string. What is the best way to update
the pickle? The only thought I have is to read all the data with the old
class module, store the data in some nonpickle format, and then, with
another program, read the nonpickle-format file and rewrite the pickle
with the class module in the new location.
You could overwrite Unpickler.find_class():

import pickle
from cStringIO import StringIO

class AliasUnpickler(pickle.Unpickler):
def __init__(self, aliases, *args, **kw):
pickle.Unpickler.__init__(self, *args, **kw)
self.aliases = aliases
def find_class(self, module, name):
module, name = self.aliases.get((module, name), (module, name))
return pickle.Unpickler.find_class(self, module, name)

def loads(aliases, str):
file = StringIO(str)
return AliasUnpickler(aliases, file).load()

if __name__ == "__main__":
import before, after
data = before.A()
print data.__class__, data
dump = pickle.dumps(data)
data = loads({("before", "A"): ("after", "B")}, dump)
print data.__class__, data

In the example the aliases dictionary maps (module, classname) pairs to
(module, classname) pairs. Of course this only works when the class layout
wasn't changed.

Peter
May 21 '07 #3
En Mon, 21 May 2007 16:24:55 -0300, Berthold Höllmann
<bh***@despammed.comescribió:
Jeffrey Barish <je*********@earthlink.netwrites:
>I have a class derived from string that is used in a pickle. In the new
version of my program, I moved the module containing the definition of
the class. Now the unpickle fails because it doesn't find the module.
I

You can fiddle with the file class used reading the pickled file. I.e.
the "read()" method could replace each instance of "foo.myclass" by
"greatnewmodule.mynewclass" could bring you back in the game.
There is a hook in the pickle module (load_global or find_global) that you
can override instead, and it's exactly for this usage, see:
http://docs.python.org/lib/pickle-sub.html

--
Gabriel Genellina

May 22 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Marc | last post by:
Hi all, I was using Tkinter.IntVar() to store values from a large list of parts that I pulled from a list. This is the code to initialize the instances: def initVariables(self): self.e =...
1
by: Thomas Aanensen | last post by:
Hi all. I'm sending a class over a socket connection, and I want to use this class at the new location. The problem is that I get a "module blah does not exist" error. Is it possible for me...
4
by: harold fellermann | last post by:
Hi all, I have a problem pickling an extension class. As written in the Extending/Embedding Manual, I provided a function __reduce__ that returns the appropreate tuple. This seams to work fine,...
3
by: syd | last post by:
Hello all, In my project, I have container classes holding lists of item classes. For example, a container class myLibrary might hold a list of item classes myNation and associated variables...
6
by: Kent Johnson | last post by:
Is there a way to persist a class definition (not a class instance, the actual class) so it can be restored later? A naive approach using pickle doesn't work: >>> import pickle >>> class...
6
by: Marco Lierfeld | last post by:
Hello there, I want to save an instance of a class containing a dictionary with the pickle-module. The class looks like this: class subproject: configuration = {} build_steps = #...
2
by: Peter Bengtsson | last post by:
Hi, I'm trying to pickle an object instance of a class that is like a dict but with a __getattr__ and I'm getting pickling errors. This works but is not good enough. $ python2.4 .... pass...
0
by: Brian L. Troutwine | last post by:
I've a need to pickle arbitrary class hierarchies, which, luckily, can be made to conform to the pickle protocol. At the moment, however, I'm having a rather hard time discovering which classes in...
4
by: PBlitz | last post by:
I want to save the content of a custom made OrderedDict. (I got the OrderedDict from http://aspn.activestate.com/ASPN/Python) The pickle modul seemed to be the solution for the job. At first I...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.