Согласно MRO, вызов переходит на H
после D
, и поэтому, если вам нужно отправить c
, класс D
должен будет принять его и отправить 3 параметра ie. H
будет вызываться D
. Например:
class A(object):
def __init__(self, a):
print('a')
print('__init__', locals())
class B(A):
def __init__(self, a, b):
print('b')
super(B, self).__init__(a)
print('__init__', locals())
class C(B):
def __init__(self, a, b):
print('c')
super(C, self).__init__(a, b)
print('__init__', locals())
class D(C):
def __init__(self, a, b, *args, **kwargs):
print('d', args, kwargs)
super(D, self).__init__(a, b, args, kwargs)
print('__init__', locals())
class E(D):
def __init__(self, a, b, *args, **kwargs):
print('e', args, kwargs)
super(E, self).__init__(a, b)
print('__init__', locals())
class F(C):
def __init__(self, a, b):
print('f')
super(F, self).__init__(a, b)
print('__init__', locals())
class G(F):
def __init__(self, a, b, c):
print('g')
super(G, self).__init__(a, b)
print('__init__', locals())
class H(G):
def __init__(self, a, b, c, *args, **kwargs):
print('h')
super(H, self).__init__(a, b, c)
print('__init__', locals())
class I(E,H):
def __init__(self, a, b, c):
print('i')
super(I,self).__init__(a, b, c)
#E.__init__(self,a, b)
#H.__init__(self,a, b, c)
print('__init__', locals())
for c in I.__mro__:
print(c)
I(0, 1, 2)
Этот код работает (я изменил c
как аргумент вместо **kwarg
). Другой способ - если вы поменяете порядок наследования E
, H
, MRO сработает, и вам не нужно будет это делать, или используйте E.__init__()
и H.__init__()
по отдельности. В этом случае MRO снова меняется, и общие классы будут вызываться дважды, если это необходимо.
Для MRO я нашел этот ответ и этот пост в блоге Гвидо Ван Россум (также связанный в другом ответе), который может помочь вам понять алгоритм MRO в python.