0

I am not sure how object of a parent class is created in Python. Consider a following scenario.

class Animal():
    def __init__(self):
        print("Animal is created")

    def eat(self):
        print("I am eating")

class Dog(Animal):

    def __init__(self, breed, name, spots):
        self.breed = breed
        self.name = name
        self.spots = spots

    def bark(self):
        print("Woof! My name is {}".format(self.name))

my_dog = Dog(breed="lab", name="Sam", spots=False)

This does not print "Animal is created".

class Animal():
    def __init__(self):
        print("Animal is created")

    def eat(self):
        print("I am eating")

class Dog(Animal):

    def __init__(self, breed, name, spots):
        Animal.__init__(self)
        self.breed = breed
        self.name = name
        self.spots = spots

    def bark(self):
        print("Woof! My name is {}".format(self.name))

my_dog = Dog(breed="lab", name="Sam", spots=False)

Whereas this prints "Animal is created"

But in both the cases I am able to access eat() method of Animal class from Dogs instance (my_dog). This means Animal is created in both the cases. Then why I don't see Animals constructor getting called in case#1?

ThinkGeek
  • 4,749
  • 13
  • 44
  • 91
  • 1
    You need to use `super`. – Red Cricket Oct 01 '18 at 03:30
  • The other question is asking how `super` works. This question is asking how `__init__` gets called. So, not a duplicate. – luther Oct 01 '18 at 03:41
  • 1
    "But in both the cases I am able to access eat() method of Animal class from Dogs instance (my_dog). This means Animal is created in both the cases. " No, that is not how it works. Only a `Dog` object is created which *is* an `Animal` object, but there is only one instance. Instances have *access* to all methods in their class and the classes they inherit from. Remember, *methods belong to the class, not the instance*. – juanpa.arrivillaga Oct 01 '18 at 03:47
  • 1
    @RedCricket This is not a duplicate. Please read the question properly before acting on it. – ThinkGeek Oct 01 '18 at 03:58
  • @eyllanesc This is not a duplicate. Please read the question properly before acting on it. – ThinkGeek Oct 01 '18 at 03:58
  • 1
    @LokeshAgrawal Have you read the answers? Do you understand that when you inherit from a class you have to call the father's methods, and that does not mean that an object of the parent class has been created, but that the child needs to initialize some properties that the parent object I inherit it. For example, let's say that the Animal class has an attribute number of legs and that depends on how it walks, so as the Dog class inherits from Animal it has to initialize the number of legs that the parent class inherits. – eyllanesc Oct 01 '18 at 04:06
  • @LokeshAgrawal [cont.] As the classes indicate they do not belong to the instance, they are part of the class. – eyllanesc Oct 01 '18 at 04:07
  • 1
    But you have to understand that this question is the lines of whether parent object gets created automatically or not and this has nothing to do with the question you referred as duplicate of. I hope you understand this. – ThinkGeek Oct 01 '18 at 04:19

1 Answers1

1

You should be calling the parent class (Animal) __init__ method in the Dog __init__ method. To get a handle on the parent class you can use super. This is considered better practice than Dog.__init__ since it doesn't explicitly require the name of the parent class.

class Dog(Animal):

    def __init__(self, breed, name, spots):
        super().__init__()
        self.breed = breed
        self.name = name
        self.spots = spots
Alex
  • 18,484
  • 8
  • 60
  • 80
  • My question is what if I dont. If I dont then also I am able to access parents method from childs object. – ThinkGeek Oct 01 '18 at 03:32
  • Sure you can still access parent methods but why would you expect the parents `__init__` to be called automatically? – Alex Oct 01 '18 at 03:34
  • If the parent __init__ is not called then how the parent object is created? As per my understanding __init__ is called anytime an object of a class is created. – ThinkGeek Oct 01 '18 at 03:36
  • @LokeshAgrawal You can examine the order those methods are called using `Dog.mro()` – Alex Oct 01 '18 at 03:36
  • `__init__` just initialized an object - it doesn't create one. You might be thinking of [`__new__`](https://docs.python.org/3/reference/datamodel.html#object.__new__). – Alex Oct 01 '18 at 03:37
  • @LokeshAgrawal a paren't object *is not created*, and just because the `__init__` of the paren't class is called doesn't mean a parent-class instance is created. It's just that instances of classes that inherit from the parent class have access to those methods – juanpa.arrivillaga Oct 01 '18 at 03:48
  • You mean to say that I am accessing parent class methods and not the parent object method. If true, then this makes sense to me. – ThinkGeek Oct 01 '18 at 03:52