Why does calling super () in the parent class __init __ () alter the behavior of the subclass __init __ ()?

I am trying to understand the behavior of super() in the context of multiple inheritance. I am confused why calls to super() in parent classes in test2.py call __init__() for both parents?

test1.py

 #!/usr/bin/env python class A(object): def __init__(self): self.A = "A" print self.A class B(object): def __init__(self): self.B = "B" print self.B class C(A, B): def __init__(self): self.C = "C" print self.C super(C, self).__init__() if __name__ == '__main__': print "Without super() in parent __init__():" c = C() print c.__dict__ print C.__mro__ 

gives:

 $ ./test.py Without super() in parent __init__(): C A {'A': 'A', 'C': 'C'} (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>) 

test2.py

 #!/usr/bin/env python class A(object): def __init__(self): self.A = "A" print self.A super(A, self).__init__() class B(object): def __init__(self): self.B = "B" print self.B super(B, self).__init__() class C(A, B): def __init__(self): self.C = "C" print self.C super(C, self).__init__() if __name__ == '__main__': print "With super() in parent __init__():" c = C() print c.__dict__ print C.__mro__ 

gives:

 $ ./test2.py With super() in parent __init__(): C A B {'A': 'A', 'C': 'C', 'B': 'B'} (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>) 
+4
source share
1 answer

Your mistake in your comment:

 super(C, self).__init__() <-- call to object.__init__() 

This is not a call to object.__init__ . The reason you pass both the C class and the self instance to super is because it knows what to call next, not only based on the superclasses of the class, but based on the MRO instance. Essentially, super(C, self).__init__ means "call the __init__ class after C in self MRO."

This is the whole point of super --- it allows co-inheritance, when a class can simply call super mean "transfer control to the next class in the MRO", without having to know the time the class was defined, which class.

Therefore, when you call super(C, self).__init__ , which calls A.__init__ , because A is the next class after C in the MRO. Then, when A calls super(A, self).__init__ , which calls B.__init__ , because B is the class after A in the MRO.

(Note that your messages are printed in the reverse order --- B, A, C --- because you print each message after calling the superclass method. Therefore, the first message does not print until execution is fully started until B.__init__ , and then other messages are printed on the return path through the inheritance tree.)

+6
source

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


All Articles