OnStrike
OnStrike

Reputation: 748

Is it acceptable to initialize the parent class from within the subclass __init__()?

Is it good practice to initialize a parent class from within the subclass, so that the parent class attributes are available to the created subclass instance? Are there alternatives or best practices in doing so?

As an example:

class Animal(object):
    def __init__(self, name, weight, cute=False, image=None):
        #Instantiation attributes
        self.name = name
        self.weight = weight
        self.cute = cute
        self.image = image
        #Attributes common to all animals
        self.extinct = False
    def get_animal_stats(self):
        print arbitrary_animal_stat

class Dog(Animal):
    def __init__(self, name, weight):
        Animal.__init__(self, name, weight, cute=True, image="dog.com")
        #Additional attributes unique to dogs
        self.number_legs = 4
        self.teeth = True
    def make_noise(self):
        print "Bark!"

As I understand it, without initializing the parent class during the subclass initialization, the subclass object only has access to its own attributes (ie. number_legs and teeth, and make_noise) and not the parent classes attributes or methods (ie. extinct, and get_animal_stats).

I find myself writing many small classes for predefined objects but have to initialize the parent with the child. In this way, I can create a simple Animal on the fly or create a more descriptive Animal through the Dog subclass.

What is the proper way to access Parent attributes and methods from the subclass instance? Am I misunderstanding the use of subclasses?

Upvotes: 2

Views: 1382

Answers (3)

Joel Cornett
Joel Cornett

Reputation: 24788

Not only is it acceptable, you should almost always call the parent class's constructor. The only reason you would not do so is if you

  1. are absolutely sure that there will never be any initialization code defined in the parent class that is necessary for the object to function and
  2. You want to explicitly override the parent class's initialization behavior.

With new style classes (those that inherit from object), it is better to use super() as it takes care of resolution order in cases of multiple inheritance. In Python 2.7, use:

class ParentFooA(GrandparentFoo):
    def __init__(self):
        some_important_initialization_code()

class ChildFoo(ParentFoo):
    def __init__(self):
        super(ChildFoo, self).__init__()

Note that another nice property is that you don't have to use the name ParentFoo anywhere in ChildFoo except when you define inheritance (for instance, in the line class ChildFoo(...)). It also works for other methods:

class ChildFoo(ParentFoo):
    ...
    def do_buzz(self):
        super(ChildFoo, self).do_buzz()

super() does not work for old-style classes (that is, classes that don't inherit from object). This means that with much of the standard library, you still have to call the parent class's constructor explicitly. So in this case:

class OldStyleParent:
    def __init__(self):
        ...

You would have to call OldStyleParent.__init__() explicitly in __init__().

In Python 3, super's syntax is simply:

class ChildFooInPython3(ParentFoo):
    def __init__(self):
        super().__init__()

Upvotes: 2

chunpoon
chunpoon

Reputation: 970

class Dog(Animal):
    def __init__(self, name, weight):
        super(Dog, self).__init__(name, weight, cute=True, image="dog.com")
        #Additional attributes unique to dogs
        self.number_legs = 4
        self.teeth = True
    def make_noise(self):
        print "Bark!"

Upvotes: -1

TStand90
TStand90

Reputation: 89

Nothing wrong with that, although you might want to use super():

super(Dog, self).__init__...

Or in Python 3:

super().__init__...

Upvotes: 1

Related Questions