Bob*_*ano 7 python multiple-inheritance
我正在尝试使用多重继承向我拥有的现有类之一添加一些功能。问题是这个新类和我当前的基类在它们的构造函数中有不同的参数。即新类有 1 个额外的参数。经过一番谷歌搜索,我明白我可以将 **kwargs 添加到当前基类(少一个参数的基类)。例子:
class A(object):
def __init__(self, a):
print('__init__', locals())
class B(A):
def __init__(self, a, b):
super(B, self).__init__(a)
print('__init__', locals())
class C(B):
def __init__(self, a, b):
super(C, self).__init__(a, b)
print('__init__', locals())
class D(C):
def __init__(self, a, b):
super(D, self).__init__(a, b)
print('__init__', locals())
class E(D):
def __init__(self, a, b, *args, **kwargs):
super(E, self).__init__(a, b)
print('__init__', locals())
class F(C):
def __init__(self, a, b):
super(F, self).__init__(a, b)
print('__init__', locals())
class G(F):
def __init__(self, a, b, c):
super(G, self).__init__(a, b)
print('__init__', locals())
class H(G):
def __init__(self, a, b, c):
super(H, self).__init__(a, b, c)
print('__init__', locals())
class I(E, H):
def __init__(self, a, b, c):
super(I, self).__init__(a, b, c=c)
print('__init__', locals())
for c in I.__mro__:
print(c)
I(0, 1, 2)
Run Code Online (Sandbox Code Playgroud)
但我收到此错误:
<class '__main__.I'>
<class '__main__.E'>
<class '__main__.D'>
<class '__main__.H'>
<class '__main__.G'>
<class '__main__.F'>
<class '__main__.C'>
<class '__main__.B'>
<class '__main__.A'>
<class 'object'>
Traceback (most recent call last):
File "/tmp/c.py", line 58, in <module>
I(0,1,2)
File "/tmp/c.py", line 50, in __init__
super(I, self).__init__(a, b, c=c)
File "/tmp/c.py", line 26, in __init__
super(E, self).__init__(a, b)
File "/tmp/c.py", line 20, in __init__
super(D, self).__init__(a, b)
TypeError: __init__() missing 1 required positional argument: 'c'
Run Code Online (Sandbox Code Playgroud)
根据 MRO,调用将转到Hafter D,因此,如果您需要发送c,类D将需要接受它并发送 3 个参数,即 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)
Run Code Online (Sandbox Code Playgroud)
这段代码有效,(我已更改c为 arg 而不是**kwarg)。另一种方法是,如果你交换E,H继承顺序,MRO 就会起作用,你就不需要这样做,或者单独使用E.__init__()和。H.__init__()在这种情况下,MRO再次发生变化,如果需要的话,公共类将被调用两次。
对于 MRO,我找到了这个答案和Guido Van Rossum 的这篇博客文章(也在另一个答案中链接),这可能会帮助您深入了解 python 中的 MRO 算法。