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@python.org
http://mail.python.org/mailman/listinfo/tutor


_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor

Reply via email to