Inheritance and Overriding __init__ in python


Question

I was reading 'Dive Into Python' and in the chapter on classes it gives this example:

class FileInfo(UserDict):
    "store file metadata"
    def __init__(self, filename=None):
        UserDict.__init__(self)
        self["name"] = filename

The author then says that if you want to override the __init__ method, you must explicitly call the parent __init__ with the correct parameters.

  1. What if that FileInfo class had more than one ancestor class?
    • Do I have to explicitly call all of the ancestor classes' __init__ methods?
  2. Also, do I have to do this to any other method I want to override?
1
120
5/5/2014 4:08:07 PM

Accepted Answer

The book is a bit dated with respect to subclass-superclass calling. It's also a little dated with respect to subclass built-in classes.

It looks like this nowadays.

class FileInfo(dict):
    """store file metadata"""
    def __init__(self, filename=None):
        super( FileInfo, self ).__init__()
        self["name"] = filename

Note the following.

  1. We can directly subclass built-in classes, like dict, list, tuple, etc.

  2. The super function handles tracking down this class's superclasses and calling functions in them appropriately.

147
4/15/2009 8:49:52 PM

In each class that you need to inherit from, you can run a loop of each class that needs init'd upon initiation of the child class...an example that can copied might be better understood...

class Female_Grandparent:
    def __init__(self):
        self.grandma_name = 'Grandma'

class Male_Grandparent:
    def __init__(self):
        self.grandpa_name = 'Grandpa'

class Parent(Female_Grandparent, Male_Grandparent):
    def __init__(self):
        Female_Grandparent.__init__(self)
        Male_Grandparent.__init__(self)

        self.parent_name = 'Parent Class'

class Child(Parent):
    def __init__(self):
        Parent.__init__(self)
#---------------------------------------------------------------------------------------#
        for cls in Parent.__bases__: # This block grabs the classes of the child
             cls.__init__(self)      # class (which is named 'Parent' in this case), 
                                     # and iterates through them, initiating each one.
                                     # The result is that each parent, of each child,
                                     # is automatically handled upon initiation of the 
                                     # dependent class. WOOT WOOT! :D
#---------------------------------------------------------------------------------------#



g = Female_Grandparent()
print g.grandma_name

p = Parent()
print p.grandma_name

child = Child()

print child.grandma_name

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon