views:

131

answers:

1

I know this has been discussed a number of times before, but there was never an explanation of what's going on "under the hood".

Can anyone provide a detailed explanation as to why commenting-in the last line of code causes an error to be raised? I know that that object.__init__ doesn't take any arguments, but why does the code work when the line is commented out?

class A:
   def __init__(self, a):
      print("A constructor")
      super().__init__(a)
      self.a = a
      print("A constructor end")

class B:
   def __init__(self, b):
      print("B constructor")
      super().__init__()
      self.b = b
      print("B constructor end")


class C(A, B):
   def __init__(self, x):
      super().__init__(x)


c = C(42)
#a = A(33)
+2  A: 

In Python 3 every method becomes a closure with a hidden value added for the "current class" being defined. This is accessed by super() (with no arguments).

Super returns an object which uses the class's Method Resolution Order (MRO), and for C instances this has B after A.

Without finding B in the MRO, super().__init__ in A will call object.__init__, to which you can't pass any parameters.

You can view the MRO for a class by looking at SomeClass.__mro__.

Though mostly talking about 2.x, you may want to read http://fuhm.net/super-harmful/.

Roger Pate