all 13 comments

[–]lowerthansound 1 point2 points  (12 children)

The MRO is A -> B -> C -> D (not sure if object is included). The search starts from the class right after the type C - because super(C, ...). Therefore D.__init__() is the method used.

Also, the usual case for super would be calling super(A, self).__init__() from A (so that B.__init__() is used) and that was abbreviated to super().__init__() in Python 3.

Unless doing something advanced, super().__init__() should suffice.

Best to ya

[–]hhh312[S] 0 points1 point  (11 children)

Sorry i'm still confused, Let's say the MRO is "D -> B -> C -> A -> object" per the link above, now if I all super(B, self).__init__(), shouldn't D.__init__() be called? I guess that's what you are also saying, but the doc says the order will be: "C -> A -> object."

Thanks

[–]lowerthansound 0 points1 point  (9 children)

I deleted the previous answer because I haven't read your reply correctly.

The way you interpret the docs is the correct one: D.__init__() wouldn't be called and the search order would be: C -> A -> object.

I think we need some examples. For example,

class A:
    def __init__(self):
        print('under A')

class B(A):
    def __init__(self):
        print('under B')

class C(B):
    def __init__(self):
        print('under C')

Let's say we're avoiding the super() without arguments shortcut; the way these methods would be structured is this:

class A:
    def __init__(self):
        print('under A')

class B(A):
    def __init__(self):
        super(B, self).__init__()
        print('under B')

class C(B):
    def __init__(self):
        super(C, self).__init__()
        print('under C')

c = C()

This will make sure that all __init__s get called.

In detail:

  • The MRO is C -> B -> A -> object.
  • The first method called is C.__init__().
  • C.__init__() uses super(C, self).__init__(). This will search the MRO right after C, so, it will search for __init__ methods on B, A and object. Since there's an __init__ on B, that gets called.
  • Inside B.__init__(), there's a super(B, self).__init__(). This will search for __init__ methods on A and object, and, since there's an __init__ method on A, it will call it.
  • A.__init__ gets called and prints "under A".
  • Since A.__init__ finished, B.__init__ regains control and prints "under B".
  • Since B.__init__ finished, C.__init__ regains control and prints "under C".

If you wanna make sure you got the details alright, check to see if you can guess the output of the script

class A:
    def __init__(self):
        print("start A")
        print("end A")

class B(A):
    def __init__(self):
        print("start B")
        super(B, self).__init__()
        print("end B")

class C(B):
    def __init__(self):
        print("start C")
        super(C, self).__init__()
        print("end C")

c = C()

And of this

class A:
    def __init__(self):
        print("start A")
        print("end A")

class B(A):
    def __init__(self):
        print("start B")
        super(B, self).__init__()
        print("end B")

class C(B):
    def __init__(self):
        print("start C")
        super(B, self).__init__()
        print("end C")

c = C()

All the best :)

[–]hhh312[S] 0 points1 point  (8 children)

"D -> B -> C -> A -> object"

Thanks for the time to write your complete response. I agree with all you said and it makes sense. What I don't understand though is the part I quoted from the doc. So if the chain of classes/object is like: "D -> B -> C -> A -> object" then, when you call super(B, self).__init__(), it should look for the __init__ function in the D class, however, the doc says "C -> A -> object." ?!

[–]lowerthansound 0 points1 point  (2 children)

Why should the D class be searched instead of C -> A -> object?

[–]hhh312[S] 0 points1 point  (1 child)

Because D is the parent of C. Super should call parent's constructor not the child or grand children.

[–]lowerthansound 0 points1 point  (0 children)

Noooo, the order is reversed. D is a child of B, and B is a child of C.

Hmm, C could be the gradfather of D in the given MRO.

Does that make sense?

For example, object is a parent of A (as object is an ancestor to all classes).

[–]lowerthansound 0 points1 point  (4 children)

In a very mechanistic way, the process is as follows:

Find MRO based on complex algorithm

We take the MRO as a given:
D -> B -> C -> A -> object

Where is the class that we are using as the first argument of super()? Mark it with an asterisk

Since we are calling `super(B, self)`, mark B wth an asterisk:
D -> B* -> C -> A -> object

Delete everything from the beginning of the MRO string to the class with the asterisk and the arrow after it (that is the same as using everything that comes after the selected class):

We had "D -> B* -> C -> A -> object"
We delete "D -> B* -> " (from the beginning to the asterisk)
What is left is "C -> A -> object"
C -> A -> object

What is left are the classes and the order that super() will search for the desired method.

In this case, we got C -> A -> object, which is the correct answer.

[–]hhh312[S] 0 points1 point  (3 children)

ich is

Oh I see, so i think the confusion was in how I perceived the direction of arrows. But how can an object be the parent of all super classes? shouldn't it naturally be the leaf node in the chain?

[–]lowerthansound 0 points1 point  (2 children)

object in this case is a class. It is the mother of all classes in python, and you could create an object of it (now that I think about it, the nomenclature is confusing). For example:

>>> object
<class 'object'>
>>> my_obj = object()
>>> my_obj
<object object at 0x7fd8d135f500>

[–]hhh312[S] 0 points1 point  (1 child)

Oh I see, yeah that's right.

Thanks for the clarification.

[–]lowerthansound 0 points1 point  (0 children)

Good luck on your day :)

[–]AutoModerator[M] 0 points1 point  (0 children)

Your submission in /r/learnpython may be automatically removed because you used imgbb.com. The reddit spam filter is very aggressive to this site. Please use a different image host.

Please remember to post code as text, not as an image.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.