newb __init__ inheritance

Ethan Furman ethan at stoneleaf.us
Thu Mar 8 12:34:20 EST 2012


hyperboogie wrote:
> Hello everyone.
> 
> This is my first post in this group.
> I started learning python a week ago from the "dive into python" e-
> book and thus far all was clear.
> However today while reading chapter 5 about objects and object
> orientation I ran into something that confused me.
> it says here:
> http://www.diveintopython.net/object_oriented_framework/defining_classes.html#fileinfo.class.example
> 
> "__init__ methods are optional, but when you define one, you must
> remember to explicitly call the ancestor's __init__ method (if it
> defines one). This is more generally true: whenever a descendant wants
> to extend the behavior of the ancestor, the descendant method must
> explicitly call the ancestor method at the proper time, with the
> proper arguments. "
> 
> However later on in the chapter:
> http://www.diveintopython.net/object_oriented_framework/userdict.html
> 
> it says:
> "Methods are defined solely by their name, and there can be only one
> method per class with a given name. So if a descendant class has an
> __init__ method, it always overrides the ancestor __init__ method,
> even if the descendant defines it with a different argument list. And
> the same rule applies to any other method. "
> 
> My question is if __init__ in the descendant class overrides __init__
> in the parent class how can I call the parent's __init__ from the
> descendant class - I just overrode it didn't I?
> 
> Am I missing something more fundamental here?
> Thanks

An excellent question.

What you subclass you are creating a new, different class.

class A(object):
     def __init__(self):
         print("this is class A's __init__")
     def method1(self, value):
         print(value)

class B(A):
     def __init__(self):
         print("this is class B's __init__")

test = B()
test.method1('42')

When it says that the subclass overrides methods of the same name, it 
means that if it finds the method in the subclass, it will stop looking 
and use the one it found.

So in the example above when Python creates test it will find __init__ 
in B and so won't bother looking in A for it.  However, when looking for 
'method1' Python does not find it in B, and so looks in A for it and, 
finding it there, uses that as B's method1.

If you want B's __init__ to also call A's __init__, you have to so 
explicity:

     def __init__(self):
         A.__init__(self)

or

     def __init__(self):
         super(B, self).__init__()

or with Python 3

     def __init__(self):
         super().__init__()

~Ethan~



More information about the Python-list mailing list