Multiple Inheritance with kwargs
Consider how you might instantiate C
:
c = C(a=3, b=5, c=9)
C.__init__
gets all the keyword arguments, but only uses the one for its own parameter c
. The rest are passed on for the next __init__
method in the chain. In this case, that's A.__init__
, which "pulls out" the argument for a
and passes b
on to B.__init__
. B
uses that and passes on the (now-empty) set of keyword arguments to the next method, object.__init__
. Because all keyword arguments have been "claimed" and processed by other classes, object.__init__
succeeds.
Because of how the MRO is constructed, classes that properly use super()
guarantee collectively that **kwargs
will be empty by the time object.__init__
is called.
In this example B
would have worked the same if it was defined as you say (point 1) and C
is as is (and there is no other use of it).
As for point 2: A call to constructor of super()
would indeed fail as indicated, if there were still keyword arguments left, e.g.:
c = C(a=1, b=2, c=3, d=4)
# -> TypeError: object.__init__() takes exactly one argument (the instance to initialize)
As the class B
is (originally) written, it would be also OK if used in reverse order as you say, or if there was one (or) more super-class(es), e.g.:
class D:
def __init__(self, d, **kwargs):
super().__init__(**kwargs)
self.d = d
class C(A,B,D):
...