Simple python inheritance

class Animal(object): def __init__(self, nlegs=4): print '__init__ Animal' self.nlegs = nlegs class Cat(Animal): def __init__(self, talk='meow'): print '__init__ Cat' self.talk = talk class Dog(Animal): def __init__(self, talk='woof'): print '__init__ Dog' self.talk = talk 
  • Why doesn't my cat tom = Cat() have the nlegs attribute?
  • Should we explicitly call Animal.__init__() from inside Cat.__init__ , or should we do something more fancy, say, with super ?
  • What if I want to create a cat with 5 legs, do I need to add additional arguments to the Cat.__init__ ?
+6
source share
3 answers

To build on what everyone else said, yes, you need to call the parent method __init__ .

It’s usually better to use super. However, in some cases (especially when you inherit from multiple classes) this can be a big problem. I will not go into details, there is no shortage of various articles that discuss it . (In addition, there are some oddities with some other “special” functions. For example, you can make super(SomeCls, self).__getitem__(5) , but super(SomeCls, self)[5] will not work.)

As a simplified example of why to use it, you can make Dog and Cat inherit from Mammal (which inherits from Animal ) and not change places in the code other than the Dog and Cat class inherit from.

As for why your tom instance does not have tom.nlegs , it is because you did not call the Animal __init__ method.

Also remember that not everything needs to be set during initialization. In this example, it makes sense not to set things like nlegs in the __init__ method. Instead, just set it directly in the class. For instance.

 class Mammal(object): nlimbs = 4 def __init__(self): print "I'm a mammal!" class Cat(Mammal): def __init__(self, color="calico"): self.color = color super(Cat, self).__init__() print "I have {0} legs I am {1}".format(self.nlimbs, self.color) class FiveLeggedCat(Cat): nlimbs = 5 

Basically, if something can change from instance to instance (for example, the color of a cat) or should be done during initialization (for example, when opening a file), then it should probably be set to __init__ .

Otherwise, if this is what we want to be the same for any instance of the class, you can install it cleaner to install it directly in the class definition.

In addition, attributes set in this way will be available for documentation tools (for example, the built-in help function), while attributes set during initialization will not.

+8
source

Use super :

 class Cat(Animal): def __init__(self, talk='meow', num_legs=4): print 'Hay cat' self.talk = talk super(Cat, self).__init__(num_legs) tom = Cat() #tom is a normal cat bob = Cat('Nyan', 3) #bob is a japanese defective cat 
+2
source

You need to look at Python super() docs. For example, you usually start (or end) your Cat.__init__() method with a call to super(Cat, self).__init__(<any args>) .

+1
source

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


All Articles