[Tutor] Poorly understood error involving class inheritance

David Perlman dperlman at wisc.edu
Mon Oct 5 22:41:08 CEST 2009


OK, I thought I had this one fixed but it was weirder than I thought.   
I think I understand what's going on, but I wanted to check with the  
experts here.

I have the following class definition, which does not subclass anything:

class oneStim:
     def __init__(self, time, mods=[], dur=None, format='%1.2f'):
         self.time=time
         self.mods=mods
         self.dur=dur
         self.format=format

     def __cmp__(self,other):
         return cmp(self.time,other.time)

     def __repr__(self):
         timestr=self.format % self.time
         if self.mods == []:
             modstr=''
         else:
             modstr = '*' + ','.join(self.format % i for i in self.mods)
         if self.dur == None:
             durstr = ''
         else:
             durstr = ':' + (self.format % self.dur)
         return timestr + modstr + durstr

     def __len__(self):
         return len(self.__repr__())


 >>> a=oneStim(40)
 >>> a
40.00
 >>> a.mods.append(3)
 >>> a
40.00*3.00
 >>> a.dur=10
 >>> a
40.00*3.00:10.00
 >>> a.mods.append(1)
 >>> a
40.00*3.00,1.00:10.00

So far so good, that's exactly what it's supposed to do.  But now look:

 >>> b=oneStim(50)
 >>> b
50.00*3.00,1.00

The mods that were added to the first instance of oneStim also appear  
in the second, newly created instance!

It appears that what is happening here is that the __init__() method  
is being parsed by the interpreter once at initial run, and at that  
time the statement "mods=[]" is being parsed, which means that the []  
object is being instantiated once there at the beginning.  So every  
instantiation of class oneStim ends up sharing a reference to the same  
list object, instead of each one having its own.

I fixed this by changing it to "mods=None" and then setting it in the  
body of the __init__ method.  Works fine now.

My question is, is this just a quirky misbehavior, or is there a  
principled reason why the code I have shown above only instantiates  
the empty list in the arguments once?

Thanks for any insight.  As I said, I got it to work fine now, so this  
isn't critical, but I'm curious to understand why things work the way  
they do.  :)

--
-dave----------------------------------------------------------------
"Pseudo-colored pictures of a person's brain lighting up are
undoubtedly more persuasive than a pattern of squiggles produced by a
polygraph.  That could be a big problem if the goal is to get to the
truth."  -Dr. Steven Hyman, Harvard





More information about the Tutor mailing list