Pickle a list

R

Rogerio Luz

Hi All

I'd like to pickle an object instance with all values. So I
instanciate myClass and set some values including a list with more
values (in the __init__), then dump to file. I realized that the
pickled object don't saved my new list values (saved only the
"default" value) but saved a String and an int. What I'm doing wrong?
Thanks Rogerio

$ python3 pickler.py P
Dump: ['default', 1, 2, 3, 4, 5, 6, 7, 8, 9] TestStr 19900909

$ python3 pickler.py U
Load: ['default'] TestStr 19900909

# pickler.py

import sys
import pickle

class MyClass:
teste = 0
nome = None
lista = ["default"]

def __init__(self):
for reg in range(1,10):
self.lista.append(reg)
self.nome = "TestStr"
self.teste = 19900909

#main
def main(argv):
if argv[1] == "P":
with open('myClass.pickle', 'wb') as f:
myClass = MyClass()
print("Dump:",myClass.lista, myClass.nome, myClass.teste)
pickle.dump(myClass, f, pickle.HIGHEST_PROTOCOL)

elif argv[1] == "U":
with open('myClass.pickle', 'rb') as f:
myClass = pickle.load(f)
print("Load:",myClass.lista, myClass.nome, myClass.teste)

if __name__ == "__main__":
main(sys.argv)
 
I

Irmen de Jong

import sys
import pickle

class MyClass:
teste = 0
nome = None
lista = ["default"]

def __init__(self):
for reg in range(1,10):
self.lista.append(reg)

^^^^^^^^^^^^^^^^^^^^^^
This probably doesn't do what you think it does.
It actually appends a range of numbers to the class attribute 'lista',
and not to the instance attribute of that name (which doesn't exist).

If you create multiple objects of type MyClass you'll notice that
everytime the list gets longer and longer (...in *all* objects, because
they still share the single class attribute!)
self.nome = "TestStr"
self.teste = 19900909

[...snip...]

The myClass object you're pickling doesn't have a 'lista' attribute.
While you can print myClass.lista without problems, you're printing the
class attribute instead.
Pickle won't include class attributes. It just pickles the object's
__dict__. If you add a line: print(myClass.__dict__)
before the pickle() call you'll see that 'lista' is not in there. And
that means that when you read the pickle back in, the new object won't
have the 1,2,3,4,5.... numbers in the lista list, instead it just has
the initial list.

You probably want to initialize self.alist in the class's __init__
method instead. That way it is a normal object attribute and will get
pickled normally.


Irmen de Jong
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top