[Tutor] inheritance

Gonçalo Rodrigues op73418@mail.telepac.pt
Tue Nov 12 17:52:01 2002


----- Original Message -----
From: "Ike Hall" <hall@nhn.ou.edu>
To: <tutor@python.org>
Sent: Tuesday, November 12, 2002 9:25 PM
Subject: [Tutor] inheritance


> Hi all,
> a quick question I hope someone can answer for me.
>
> suppose I have some class:
>
> class blah:
>     def __init__(self,blah, blah, blah):
>          ...stuff...
>     def method(self,yak,yak,yak):
>          ...more stuff...
>     ....more methods...
>
> then I define some other class to inherit this class,
>
> class thbbt(blah):
>     def __init__(self,la,la,la):
>         ...different stuff than in blah.__init__...
>     def method(self,yakkity,yak):
>         ...different stuff than in blah.method...
>
> My question then is this:  when I call thbbt.__init__ or thbbt.method,
what
> happens?  I guess what Im trying to say is that I do not really understand
> inheritance all that well, especially if some methods that are to be
> inherited are "written over" in the class definition.  Can anyone help me?
>
> Ike
>

It goes like this: Whenever Python finds something like

<object>.<name>

It looks for <name> in the *<object>*'s __dict__, then if not found there(*)
it looks in  the object's class, and then if it is not there it crawls(**)
up the inheritance hierarchy until something is found or an AttributeError
exception is thrown. All this is done at run time - when the program is
running. This means that derived methods shadow the base ones - as one would
expect.

The following examples show this:

>>> class Test:
...  def howdy(self):
...   print "%r says howdy" % self
...
>>> class Test2(Test):
...  def howdy(self):
...   print "%r in class %r says howdy too" % (self, self.__class__)
...
>>> a = Test()
>>> a.howdy()
<__main__.Test instance at 0x010F84C0> says howdy
>>> b = Test2()
>>> b.howdy()
<__main__.Test2 instance at 0x010D81E0> in class <class __main__.Test2 at
0x010F4A40> says howdy too
>>> def anotherhowdy():
...  print "I am a classless howdy!"
...
>>> a.howdy = anotherhowdy
>>> a.howdy()
I am a classless howdy!
>>>

Of course *if* I do it as

Test.howdy(b)

Then what I am asking is for the attribute howdy of the Test class - an
unbound method - and then apply it to b, which is a Test2 instance. But the
attribute lookup rule is the same, as you can see in

>>> class A(object):
...  def test(self):
...   print "howdy"
...
>>> class B(A):
...  pass
...
>>> c = B()
>>> B.test(c)
howdy
>>>

(*) I believe this rule changed slightly in 2.2 - but I am unable to give
you the *exact* details.
(**) "crawls up the inheritance hierarchy" means exactly: for every class in
the mro of the object's class. I'll leave to the docs the explanation of
what is this exactly.

HTH,
G. Rodrigues