我有三个类:A
,B
和C
。C
继承自A
和B
(按此顺序)。 A
和B
的构造函数签名不同。如何调用两个父类的__init__
方法?
我在代码中的努力:
class A(object):
def __init__(self, a, b):
super(A, self).__init__()
print('Init {} with arguments {}'.format(self.__class__.__name__, (a, b)))
class B(object):
def __init__(self, q):
super(B, self).__init__()
print('Init {} with arguments {}'.format(self.__class__.__name__, (q)))
class C(A, B):
def __init__(self):
super(A, self).__init__(1, 2)
super(B, self).__init__(3)
c = C()
产生错误:
Traceback (most recent call last):
File "test.py", line 16, in <module>
c = C()
File "test.py", line 13, in __init__
super(A, self).__init__(1, 2)
TypeError: __init__() takes 2 positional arguments but 3 were given
我发现this resource可以用不同的参数集解释多重继承,但是他们建议对所有参数都使用
*args
和**kwargs
。我认为这很丑陋,因为我无法从子类的构造函数调用中看到将哪些参数传递给父类。 最佳答案
除非您知道自己在做什么,否则请勿使用super(baseclass, ...)
。 super()
的第一个参数告诉它寻找下一个要使用的方法时要跳过的类。例如。 super(A, ...)
将查看MRO,找到A
,然后开始在的下一个基类上查找__init__
,而不是 A
本身。对于C
,MRO是(C, A, B, object)
,因此super(A, self).__init__
将找到B.__init__
。
对于这些情况,您不想使用协作继承,而是直接引用A.__init__
和B.__init__
。仅当您所调用的方法具有相同签名或将super()
和*args
吞入不受支持的参数时,才应使用**vargs
。在这种情况下,只需要一个super(C, self).__init__()
调用,而MRO顺序中的下一个类将负责该调用的链接。
换句话说:当您使用super()
时,您无法知道MRO中的下一个类,因此该类更好地支持传递给它的参数。如果不是这种情况,请不要使用super()
。
直接调用基本__init__
方法:
class A(object):
def __init__(self, a, b):
print('Init {} with arguments {}'.format(self.__class__.__name__, (a, b)))
class B(object):
def __init__(self, q):
print('Init {} with arguments {}'.format(self.__class__.__name__, (q)))
class C(A, B):
def __init__(self):
# Unbound functions, so pass in self explicitly
A.__init__(self, 1, 2)
B.__init__(self, 3)
使用合作的
super()
:class A(object):
def __init__(self, a=None, b=None, *args, **kwargs):
super().__init__(*args, **kwargs)
print('Init {} with arguments {}'.format(self.__class__.__name__, (a, b)))
class B(object):
def __init__(self, q=None, *args, **kwargs):
super().__init__(*args, **kwargs)
print('Init {} with arguments {}'.format(self.__class__.__name__, (q)))
class C(A, B):
def __init__(self):
super().__init__(a=1, b=2, q=3)
关于python - python3中具有不同签名的多重继承,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26927571/