Python Inheritance Why is this so messy?

Possible duplicate:
Why don't Python init superclass methods start?

For instance:

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, the dog inherits from the pet. I understand the code perfectly. But why should we call init for a pet in the Dog class? Why not just call him, as in the first line of the dog class is enough (class Dog (Pet))? It seems to only create messy code. It kind of kills me inheritance in Python.

+4
source share
2 answers

Having a language causes the superclass to initialize before or after, which means you are losing functionality. A subclass may depend on the initialization of the superclass that should be launched first, or vice versa.

In addition, he would have no way of knowing which arguments to pass - the subclasses decide which values ​​are passed to the initializer, which gives more flexibility when automatically passing all arguments.

An alternative method to initialize a superclass is to use super , although it will actually initialize the superclass of the self class dynamically, by searching for it in the __mro__ object (method resolution order)

In python 2:

 super(self, Dog).__init__(self, name, "Dog") 

In python 3, you can further reduce the syntax and not repeat yourself:

 super().__init__(self, name, "Dog") 

Edit

Since you are not actually using the name argument passed to the dog, you can further reduce some syntax by accepting an arbitrary keyword and positional arguments in the Dog initializer and passing them 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 may be simple enough to not be needed, but it is useful to know when you have more arguments and / or a deeper class hierarchy.

+9
source

You can make a view an attribute of a class as follows

 class Pet(object): species = None def __init__(self, name): self.name = name 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): species = "Dog" def __init__(self, name, chases_cats): Pet.__init__(self, name) self.chases_cats = chases_cats def chasesCats(self): return self.chases_cats 
+4
source

Source: https://habr.com/ru/post/1411434/


All Articles