根据Guido's explanation on MRO。在以下示例中(Python 3语法)
>>> class A:
... def __init__(self,*args, **kwargs):
... print("Am in A")
... super().__init__(self, *args, **kwargs)
...
>>> class B:
... def __init__(self,*args, **kwargs):
... print("Am in B")
... super().__init__(self, *args, **kwargs)
...
>>> class C(A,B): #MRO - C, A, B, Object
... def __init__(self, *args, **kwargs):
... print("Am in C")
... super().__init__(self, *args, **kwargs)
...
>>> class D(B,A): #MRO - D, B, A, Object
... def __init__(self, *args, **kwargs):
... print("Am in D")
... super().__init__(self, *args, **kwargs)
...
需要从基类A和amp;中调用super()。 B为了完成派生类C&的MRO。 D即。
C的MRO - C,A,B,对象 从C的init-> C的super()调用A的init 从A的init-> A的super()调用B的init
D的MRO - D,B,A,对象 从D'开头 - > D'的super()调用B的init 从B的init-> B的super()调用A的init
然而,这导致初始化失败,
>>> C(1,2)
Am in C
Am in A
Am in B
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
File "<stdin>", line 4, in __init__
File "<stdin>", line 4, in __init__
TypeError: object.__init__() takes no parameters
因为,来自B的init-&gt; B的super()调用“object”的init,它不带参数
调用D(1,2)将产生类似的错误
如果我从B中移除super(),则D的MRO(D,B,A,Object)将停在B.将永远不会调用初始化。
>>> C(1,2)
Am in C
Am in A
Am in B
<__main__.C object at 0x7ffb07b038d0>
>>> D(1,2)
Am in D
Am in B
<__main__.D object at 0x7ffb07b03908>
>>>
我可以通过在调用它的init之前检查超类(在A&amp; B中)来解决这个问题
def __init__(self,*args, **kwargs):
print("Am in A")
if super().__doc__ != "The most base type":
super().__init__(self, *args, **kwargs)
编辑:正如评论中所建议的,我们应该有一个顶级课程,不会调用super()
这真的有必要吗?为什么object
类不能允许可选参数(*args, **kwargs
)在多重继承期间支持灵活的基类排序?
因为对象的__init__
只是传递语句
class object:
def __init__(self): # known special case of object.__init__
""" x.__init__(...) initializes x; see help(type(x)) for signature """
pass