OOP: method overriding works in mysterious ways?

Chris Mellon arkanes at gmail.com
Tue Jan 3 09:46:05 EST 2006


On 1/2/06, Mike Meyer <mwm at mired.org> wrote:
> "John M. Gabriele" <john_sips_teaz at yahooz.com> writes:
>
> > Consider the following:
> >
> > #!/usr/bin/python
> >
> > #-----------------------------------------------------------------
> > class Grand_parent( object ):
> >
> >      def speak( self ):
> >          print 'Grand_parent.speak()'
> >          self.advise()
> >
> >      def advise( self ):
> >          print 'Grand_parent.advise()'
> >          self.critique()
> >
> >      def critique( self ):
> >          print 'Grand_parent.critique()'
> >
> >
> > #-----------------------------------------------------------------
> > class Parent( Grand_parent ):
> >
> >      def speak( self ):
> >          print '\tParent.speak()'
> >          self.advise()
> >
> >      def advise( self ):
> >          print '\tParent.advise()'
> >          self.critique()
> >
> >      # ATM, the Parent is at a loss for words, and has no critique.
> >
> >
> > #-----------------------------------------------------------------
> > class Child( Parent ):
> >
> >      def speak( self ):
> >          print '\t\tChild.speak()'
> >          self.advise()
> >
> >      # Currently, the Child has no really useful advice to give.
> >
> >      def critique( self ):
> >          print '\t\tChild.critique()'
> >
> >
> > #-----------------------------------------------------------------
> > print 'speak() calls advise(), then advise() calls critique().'
> > print
> >
> > people = [ Grand_parent(), Parent(), Child() ]
> > for person in people:
> >      person.speak()
> >      print
> >
> >
> >
> > ====================
> > The output is:
> >
> > speak() calls advise(), then advise() calls critique().
> >
> > Grand_parent.speak()
> > Grand_parent.advise()
> > Grand_parent.critique()
> >
> >          Parent.speak()
> >          Parent.advise()
> > Grand_parent.critique()
> >
> >                  Child.speak()
> >          Parent.advise()
> >                  Child.critique()
> >
> >
> > What's going on here with that last "Child.critique()"? The
> > Parent called self.critique(), and since it *had* no critique()
> > method, it should've deferred to it's parent's critique()
> > method, right? But instead, somehow Child.critique() got called.
> > Why?
>
> Because that's the way Python searchs for object attributes. Nobody
> made it explicit, so I will. This is simplified, ignoring various
> complications:
>
>         When looking up a value for self.foo, you first look for
>         attribute foo of self. You then check the class of self for
>         attribute foo. You then check the parent class of the last
>         class you checked for attribute foo. You repeat that last step
>         until there is no parent class.
>
> Like I said, that's simplified. But it's sufficent to explain what
> you're seeing.

If your interested in the non-simplified complicated rules for exactly
how methods are looked up (only different than the simple case when
you get into multiple inheritence), see
http://www.python.org/2.3/mro.html

>
>        <mike
> --
> Mike Meyer <mwm at mired.org>                      http://www.mired.org/home/mwm/
> Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
> --
> http://mail.python.org/mailman/listinfo/python-list
>



More information about the Python-list mailing list