In a multiple inheritance scenario, how does Python3 pass the arguments to all the parent classes? Consider the toy program below:
class A(object):
def __init__(self, a='x', **kwargs):
print('A', kwargs)
super().__init__()
class B(object):
def __init__(self, **kwargs):
print('B', kwargs)
super().__init__()
class C(A,B):
def __init__(self, **kwargs):
print('C', kwargs)
super().__init__(**kwargs)
c = C(a='A', b='B', c='C')
The output is:
C {'a': 'A', 'b': 'B', 'c': 'C'}
A {'b': 'B', 'c': 'C'}
B {}
What I expect to do is to pass the same kwargs to all the parent classes and let them use the values as they want. But, what I am seeing is that once I'm down the first parent class A
, the kwargs is consumed and nothing is passed to B
.
Please help!
Update If the order of inheritance was deterministic and I knew the exhaustive list of kwargs that can be passed down the inheritance chain, we could solve this problem as
class A(object):
def __init__(self, a='x', **kwargs):
print('A', kwargs)
super().__init__(**kwargs)
class B(object):
def __init__(self, **kwargs):
print('B', kwargs)
super().__init__()
class C(A,B):
def __init__(self, **kwargs):
print('C', kwargs)
super().__init__(**kwargs)
c = C(a='A', b='B', c='C')
Here, since A
passes down kwargs and we know that B
would be called after it, we are safe, and by the time object.__init__()
is invoked, the kwargs would be empty.
However, this may not always be the case.
Consider this variation:
class C(B,A):
def __init__(self, **kwargs):
print('C', kwargs)
super().__init__(**kwargs)
Here, object.__init__()
invoked from class A
would raise an exception since there are still kwargs left to consume.
So, is there a general design guideline that I should be following?