class Animal(object):
def __init__(self, nlegs=4):
self.nlegs = nlegs
class Cat(Animal):
def __init__(self, talk='meow'):
self.talk = talk
class Dog(Animal):
def __init__(self, talk='woof'):
self.talk = talk
- Why does my cat
tom = Cat()not have annlegsattribute? - Should we explicitly call
Animal.__init__()from withinCat.__init__, or should we usesuperhere? - What if we want to create a cat with 5 legs, should we add additional arguments to the
Cat.__init__interface?
To build on what everyone else has said, yes, you’ll need to call the parent’s
__init__method.It’s generally best to use super. However, in certain cases (particularly when you’re inheriting from multiple classes) it can be a big gotcha. I’ll avoid going into detail, there are no shortage of various articles which discuss it. (Also, there are some oddities with some of the other “special” functions. For example, you can do
super(SomeCls, self).__getitem__(5)butsuper(SomeCls, self)[5]won’t work.)As a simplistic example of why it’s a good idea to use it, you could make
DogandCatinherit fromMammal(which inherits fromAnimal) and not have to change places in your code other than which classDogandCatinherit from.As for why your
tominstance doesn’t havetom.nlegs, it’s because you haven’t calledAnimal‘s__init__method.Also remember that not everything needs to be set at initialization time. For this example, it makes more sense not to set things like
nlegsin the__init__method. Instead, just set it directly in the class. E.g.Basically, if something is likely to change from instance to instance (e.g. the color of the cat) or needs to be done at initialization (e.g. opening a file), then it probably should be set in
__init__.Otherwise, if it’s something we want to be the same for any instance of the class, it can be cleaner to set it directly in the class definition.
Also, attributes set this way will be available to documentation tools (e.g. the built-in
helpfunction), whereas attributes set at initialization won’t be.