Pickling an instance of a class containing a dict doesn't work

M

Marco Lierfeld

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 = []
# some functions
# ...

Now I create an instance of this class, e.g.
test = subproject()
and try to save it with pickle.dump(test, file('test.pickle','wb')) or with
pickle.Pickler(file('test.pickle','wb')).save(test) it looks like
everything has worked well, but in the saved file 'test.pickle' only the
list 'build_steps' is saved - the dictionary 'configuration' is missing.
There is wether an error-message nor an exception.

When I try to save only the dictionary, there is no problem at all - the
dict is saved to the file.

I also tried the 3 different protocols (0, 1, 2), but none of them worked
for me.

I hope somebody knows what to do ;)

Thanks for reading

Marco
 
J

Jon Clements

Marco said:
The class looks like this:
class subproject:
configuration = {}
build_steps = []
# some functions
# ...

Now I create an instance of this class, e.g.
test = subproject()
and try to save it with pickle.dump(test, file('test.pickle','wb')) or with
pickle.Pickler(file('test.pickle','wb')).save(test) it looks like
everything has worked well, but in the saved file 'test.pickle' only the
list 'build_steps' is saved - the dictionary 'configuration' is missing.
There is wether an error-message nor an exception.

When I try to save only the dictionary, there is no problem at all - the
dict is saved to the file.

I also tried the 3 different protocols (0, 1, 2), but none of them worked
for me.

At a wild guess. Since pickle descends the objects hierarchy, and since
configuration and build_steps aren't local to an instance of a class,
it stores only a reference to them (so you won't see values). However,
if you change the above to:

class subproject:
def __init__(self):
configuration = { }
build_steps = [ ]

That'll probably be what you expect...

Jon.
 
J

Jon Clements

Jon said:
if you change the above to:

class subproject:
def __init__(self):
configuration = { }
build_steps = [ ]

Of course, I actually meant to write self.configuration and
self.build_steps; d0h!
 
P

Paul McGuire

Marco Lierfeld said:
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 = []
# some functions
# ...

Now I create an instance of this class, e.g.
test = subproject()
and try to save it with pickle.dump(test, file('test.pickle','wb')) or
with
pickle.Pickler(file('test.pickle','wb')).save(test)

I'm guessing that configuration and build_steps are supposed to be instance
variables, not class-level variables. It would be interesting to see what
your __init__ method looks like. I'm guessing you assign something the
self.build_steps in __init__, but self.configuration is omitted.

Try moving these initializers into the __init__ method, as:
class subproject:
def __init__(self):
self.configuration = {}
self.build_steps = []

and see if pickle starts behaving better.

-- Paul
 
M

Marco Lierfeld

Jon said:
if you change the above to:

class subproject:
def __init__(self):
configuration = { }
build_steps = [ ]

Of course, I actually meant to write self.configuration and
self.build_steps; d0h!

Thank you Jon and Paul, you both were 100% right :)

But I still don't understand, why the list was saved and the dict was not...
confusing ;)

Bye,
Marco
 
P

Peter Otten

Marco said:
Jon said:
if you change the above to:

class subproject:
def __init__(self):
configuration = { }
build_steps = [ ]

Of course, I actually meant to write self.configuration and
self.build_steps; d0h!

Thank you Jon and Paul, you both were 100% right :)

But I still don't understand, why the list was saved and the dict was
not... confusing ;)

Chances are you have inadvertently created an /instance/ attribute
build_steps which was then saved:

s = subproject()
# ...
s.configuration["name"] = "my dinner" # modifies the class attribute
s.build_steps = ["hunt", "kill", "cook"] # creates an instance attribute

Peter
 
M

Marco Lierfeld

Peter said:
Chances are you have inadvertently created an /instance/ attribute
build_steps which was then saved:

s = subproject()
# ...
s.configuration["name"] = "my dinner" # modifies the class attribute
s.build_steps = ["hunt", "kill", "cook"] # creates an instance attribute

Yes, now I see. That's the way I filled the dict and the list.

Thank you for the explanation :)

Marco
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top