0

I don't understand why the code uses the print_me method from Class D, and not the method in class A.

I did some testing using print-statements and can see that it reads the print_me-method of class D before initialising class A, but I don't understand why it doesn't do the same for class A.

class A:
    name = "Alfa"

    def __init__(self, foo):
        self.foo = foo
        foo = 100
        self.print_me()

    def print_me(self):
        print(self.name, self.foo)

class B(A):
    name = "Beta"

    def __init__(self, bar = 40):
        self.bar = bar
        print(self.name, bar)

class C:
    name = "Charlie"

class D(A, C):
    name = "Delta"

    def __init__(self, val):
        A.__init__(self, val)

    def print_me(self):
        print(self.name, "says", self.foo)

d = D(60)

The output is: Delta says 60

I thought it would be: Delta 60

Djaff
  • 173
  • 1
  • 10
  • 1
    Because the lookup starts from the "lowest" class. I'm pretty sure this behavior is the same in any other major OO language. Try to do `print(D.mro())` – DeepSpace May 13 '19 at 18:34
  • So when it looks for the print_me method, it starts looking in class D cause that is the lowest class? And because it finds one, it's okay with it and uses that? – Djaff May 13 '19 at 18:37
  • That is correct – DeepSpace May 13 '19 at 18:38
  • Loop up `method resolution order` – Perplexabot May 13 '19 at 18:47
  • Possible duplicate of [How to call Base Class's \_\_init\_\_ method from the child class?](https://stackoverflow.com/questions/19205916/how-to-call-base-classs-init-method-from-the-child-class) – sakhunzai May 13 '19 at 19:15

1 Answers1

3

Because the self you are passing to the __init__ of A is still an instance of D, not A. And the function A.__init__ is calling self.print_me, which belongs to D.

If you do a = A(); a.print_me() you'd get what you expect.

Important note: The __init__ method in python is not the actual constructor, it is just a method that is automatically called after the actual construction of the object. However, when you call it yourself, it works just like any other method.

blue_note
  • 27,712
  • 9
  • 72
  • 90
  • This answer could use an explanation (or a link to an answer that explains) the concept of MRO. If `D.print_me` will be removed then `A.print_me` will be called. Similarly, if `A.print_me` will be removed then `D.print_me` will be called. – DeepSpace May 13 '19 at 18:40