[Tutor] Pickling
Kent Johnson
kent37 at tds.net
Sun Feb 13 14:37:53 CET 2005
Johan,
The problem is in your class V. You have
> class V:
> a=[]
>
> def add(self, s):
> self.a.append(s)
The problem is that 'a' is a *class* variable, not an instance variable. The correct way to define V
is like this:
class V:
def __init__(self):
self.a=[] # Now 'a' is an instance variable
def add(self, s):
self.a.append(s)
Why does this cause the behaviour you are seeing? Let's take a look at your assign() and add()
functions:
> def assign():
> p=V()
At this point p has no 'a' attribute of its own, just the class attribute inherited from V.
> p.a = [1,2,3,4]
This assignment *creates* an 'a' attribute in the object p. Now when you pickle p, it gets the list
saved with it.
> f = open ("blah.dat", 'a')
> print 'assign:', p.a
> pickle.dump(p,f)
> f.close()
>
OK, how about add()?
> def add():
> p=V()
> p.add(1);p.add(2);p.add(3);p.add(4);
This is changing the *class* attribute 'a'! The object p has no attribute 'a', so when p is pickled,
no list is saved with it.
> print 'add:', p.a
> f = open("blah.dat", 'a')
> pickle.dump(p,f)
> f.close()
The reason you see the expected list when you run both versions is because you have changed the
class attribute.
A little dabbling in the Python interpreter might clarify a bit more:
>>> class V:
... a=[]
... def add(self, s):
... self.a.append(s)
...
>>> p=V()
>>> p.a
[]
>>> V.a
[]
>>> p.add(1)
>>> p.add(2)
>>> p.a
[1, 2]
>>> V.a
[1, 2]
p.a is actually accessing V.a.
>>> p=V()
>>> p.a = [3,4]
>>> p.a
[3, 4]
>>> V.a
[1, 2]
Now p has it's own a and V.a is unchanged.
Kent
Johan Kohler wrote:
> Hi
> I still have problems pickling and unpickling. After I couldn't get
> "complicated" objects to work, i decided to use simple lists. But now
> there seems to be a difference between assigning a list value, and using
> the .append method. Please try out the code at
> http://goose.cs.und.ac.za/python/save1.py There are two "use cases"
> WorkingCase() and BrokenCase.
>
> WorkingCase() saves data in a list using assignment, and by appending,
> and then reads it back from the file. BrokenCase performs only the
> reading back step. Now, there are no problems when the two cases are
> run consecutively. Do this once. Then comment out the WorkingCase()
> statement, and run only BrokenCase(). This should read back all the
> list entries, but all the ones created by "appending" are blank! I
> should mention, that in my application I want to append items one by one
> to the list.
>
> Please can someone help me with this? I am getting extremely frustrated
> by not being able to get supposedly simple stuff to work.
>
> Thanks in advance,
> Johan
>
>
>
>
>
>
>
>
>
>
>
> _______________________________________________
> Tutor maillist - Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
More information about the Tutor
mailing list