Possible Duplicate:
Why aren't Python's superclass init methods automatically invoked?
For example:
class Pet(object):
def __init__(self, name, species):
self.name = name
self.species = species
def getName(self):
return self.name
def getSpecies(self):
return self.species
def __str__(self):
return "%s is a %s" % (self.name, self.species)
class Dog(Pet):
def __init__(self, name, chases_cats):
Pet.__init__(self, name, "Dog")
self.chases_cats = chases_cats
def chasesCats(self):
return self.chases_cats
As you can see Dog inherits from pet. I understand the code perfectly fine. But why must we call the init for pet in the Dog class? Why isn't just calling it as in the first line of the dog class enough ( class Dog(Pet) )? It seems to only create messier code. It kind of kills the point of inheritance in Python to me.
Having the language force the super class to initialize before or after means that you lose functionality. A subclass may depend on a superclass's initialization to be run first, or vice versa.
In addition, it wouldn't have any way of knowing what arguments to pass -- subclasses decide what values are passed to an initializer, which gives more flexibility over automatically passing all arguments.
An alternative method of initializing the super-class is by using super, though this will actually initialize the super-class of self
dynamically, by looking it up in the object's __mro__
(method resolution order)
In python 2:
super(self, Dog).__init__(self, name, "Dog")
In python 3, you can further reduce the syntax, and avoid repeating yourself:
super().__init__(self, name, "Dog")
Edit:
Since you're not actually using the name
argument passed to dog, you can further reduce some syntax, by accepting arbitrary keyword and positional arguments in the Dog
initializer, and passing them up the initialization chain:
class Dog(Pet):
def __init__(self, chases_cats, *args, **kwargs):
Pet.__init__(self, *args, species="Dog", **kwargs)
self.chases_cats = chases_cats
class Pet(object):
def __init__(self, name, species, *args, **kwargs):
self.name = name
self.species = species
In your scenario, the initializer might be simple enough to not need this, but it's useful to know for when you have more arguments, and/or a deeper class hierarchy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With