Question about subclassing and overriding methods

Bruno Desthuilliers onurb at xiludom.gro
Thu Sep 7 04:09:51 EDT 2006


Frank Millman wrote:
> Hi all
> 
> Assume a simple class -
> 
> class Test(object):
>     def __init__(self,x):
>         self.x = x
>     def getx(self):
>         print self.x
> 
> Test(1).getx()
> Test(2).getx()
> Test(3).getx()
> 
> As expected, the results are 1,2,3
> 
> Assume a slight variation, where given a particular condition I want a
> particular method to behave differently. I know that I could subclass,
> but for various reasons I preferred to do it this way -
> 
> class Test(object):
>     def __init__(self,x,y=False):
>         self.x = x
>         if y:
>             self.getx = self.getx2
>     def getx(self):
>         print self.x
>     def getx2(self):
>         print self.x * 2
> 
> Test(1).getx()
> Test(2,True).getx()
> Test(3).getx()
> 
> As expected, the results are 1,4,3
> 
> Now assume a subclass of the above class, where I want the method to
> behave diferently again -
> 
> class Test2(Test):
>     def __init__(self,x,y=False):
>         Test.__init__(self,x,y)
>     def getx(self):
>         print self.x*3
> 
> Test2(1).getx()
> Test2(2,True).getx()
> Test2(3).getx()
> 
> Here I was hoping that the results would be 3,6,9

Why ???

> but they are 3,4,9.

Yes, obviously.

> I thought that getx in Test2 would override getx in Test,

It does.

> even if getx
> in Test has been replaced by getx2, 

This "replacement" happens at instance initialisation time - ie, after
the class object have been created. If you don't want this to happen,
either skip the call to Test.__init__ in Test2.__init__, or make this
call with False as second param, or redefine getx2 in Test2. Or go for a
saner design...

> but clearly that is not happening.
> Can someone explain why.

Test2(2,True) calls Test2.__init__() with a Test2 instance 'self' and
y=True. Test2.__init__() then calls Test.__init__() with the same
instance and y=True. So the branch:
 if y:
   self.getx = self.getx2
is executed on the Test2 instance.

I don't see what puzzle you here.

> Thanks
> 
> Frank Millman
> 


-- 
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"



More information about the Python-list mailing list