其他答案建议在第一个参数中添加self。
但通常在父类中对__init__的调用是由super进行的。
举个例子:class A(object):
def __init__(self, x):
print('__init__ is called in A')
self.x = x
class B(object):
def __init__(self, *args, **kwargs):
print('__init__ is called in B')
super(B, self).__init__(*args, **kwargs)
class AB(B, A):
def __init__(self, *args, **kwargs):
print('__init__ is called in AB')
super(AB, self).__init__(*args, **kwargs)
AB类包含调用构造函数和初始化器的顺序:>>> AB.__mro__
(, , , )
看,首先调用AB的__init__,然后调用B,然后调用A,最后调用object
让我们检查一下:>>> ab = AB(1)
__init__ is called in AB
__init__ is called in B
__init__ is called in A
但通过这个链的这些调用是由super发出的。当我们输入super(AB, self)时,它意味着:在self链的__mro__中找到AB之后的下一个类。
然后我们应该在B中调用super,在链中寻找B:super(B, self)之后的下一个类。
使用super而不是手动调用A.__init__(self,...)等很重要,因为这可能会导致以后出现问题。Read this for more info。
所以,如果你坚持使用super,那么就有问题了。__init__类中的方法需要不同的参数。而且您无法确定super在这些类中调用方法的顺序。在创建类时,顺序由C3 algorithm决定。在子类中,另一个类可能位于调用链之间。因此在__init__中不能有不同的参数,在本例中,您必须始终考虑所有继承链,以了解如何调用__init__方法。
例如,考虑添加C(A)和D(B)类以及它们的CD子类。然后A将不再在B之后调用,而是在C之后调用。class A(object):
def __init__(self, *args, **kwargs):
print('__init__ is called in A')
super(A, self).__init__(*args, **kwargs)
class B(object):
def __init__(self, *args, **kwargs):
print('__init__ is called in B')
super(B, self).__init__(*args, **kwargs)
class AB(B,A):
def __init__(self, *args, **kwargs):
print('__init__ is called in AB')
super(AB, self).__init__(*args, **kwargs)
class C(A):
def __init__(self, *args, **kwargs):
print('__init__ is called in C')
super(C, self).__init__(*args, **kwargs)
class D(B):
def __init__(self, *args, **kwargs):
print('__init__ is called in D')
super(D, self).__init__(*args, **kwargs)
class CD(D,C):
def __init__(self, *args, **kwargs):
print('__init__ is called in CD')
super(CD, self).__init__(*args, **kwargs)
class ABCD(CD,AB):
def __init__(self, *args, **kwargs):
print('__init__ is called in ABCD')
super(ABCD, self).__init__(*args, **kwargs)
>>> abcd = ABCD()
__init__ is called in ABCD
__init__ is called in CD
__init__ is called in D
__init__ is called in AB
__init__ is called in B
__init__ is called in C
__init__ is called in A
所以我认为在这里考虑使用delegation而不是继承是个好主意。class AB(object):
def __init__(self, x, y, z=0):
self.a = A(x,y)
self.b = B(z)
所以,您只需在AB对象中创建a和b类的A和B实例。然后可以根据需要通过引用self.a和self.b的方法使用它们。
使用与否取决于你的情况,而你的问题并不清楚。但这可能是一个值得考虑的选择。