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