用不同的参数在python中调用超类构造函数

用不同的参数在python中调用超类构造函数,python,inheritance,constructor,arguments,Python,Inheritance,Constructor,Arguments,如何使AB的构造函数使用正确的参数调用A和B的构造函数 我试过了 class A(): def __init__( self, x, y): self.x = x self.y = y class B(): def __init__( self, z=0): self.z = z class AB(A,B): def __init__( self, x, y, z=0): ? 但这给了我一个错误。您

如何使AB的构造函数使用正确的参数调用A和B的构造函数

我试过了

class A():
    def __init__( self, x, y):
        self.x = x
        self.y = y

class B():
    def __init__( self, z=0):
        self.z = z  

class AB(A,B):
    def __init__( self, x, y, z=0):
        ?

但这给了我一个错误。

您没有通过
self

class AB(A,B):
    def __init__( self, x, y, z=0):
        A.__init__(x,y)
        B.__init__(z)

请注意,如果此继承层次结构变得更复杂,您将遇到构造函数无法执行或无法重新执行的问题。如果您在2.x上,并且您的类没有从任何其他对象继承,请查看(以及带有
super的
),不要忘记从
对象继承。

其他答案建议在第一个参数中添加
self

但是通常在父类中调用
\uuuu init\uuu
是由
super
进行的

考虑这个例子:

class AB(A, B):
    def __init__(self, x, y, z=0):
        A.__init__(self, x, y)
        B.__init__(self, z)
AB
类包含调用构造函数和初始化器的顺序:

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)
但是通过这个链的这些调用是由
super
发出的。当我们键入
super(AB,self)
时,它的意思是:在
\uuuumro\uuuuuuu
self
链中找到
AB
之后的下一个类

class AB(A,B):
    def __init__( self, x, y, z=0):
        A.__init__(x,y)
        B.__init__(z)
然后我们应该在
B
中调用
super
,在
B
之后的链中查找下一个类:
super(B,self)

重要的是要使用
super
,不要手动调用
A.uuu init_uuu(self)
等,因为这可能会导致以后出现问题

因此,如果您坚持使用
super
,那么就会出现问题<类中的code>\uuu init\uu
方法需要不同的参数。您无法确定
super
调用这些类中方法的顺序。顺序由创建类时确定。在子类中,另一个类可能位于调用链的中间。因此,在AytIntIy<<代码>中,你不能有不同的参数,因为在这种情况下,你将总是考虑所有继承链来理解<代码>

例如,考虑添加<代码> C(a)< /代码>和<代码> d(b)< /代码>类和<代码> CD< /代码>子类。然后

A
将不再在
B
之后调用,而是在
C
之后调用

>>> ab = AB(1)
__init__ is called in AB
__init__ is called in B
__init__ is called in A
因此,我认为在这里考虑使用
委托
而不是继承是个好主意

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
因此,您只需在
AB
对象中创建
a
b
类的
a
b
实例。然后可以通过引用
self.a
self.b
的方法根据需要使用它们


使用或不使用授权取决于您的情况,而您的问题并不清楚。但是这可能是一个选择。

为什么你使用继承而不是委托?因为多重继承的情况应该通过使用
super
来处理,这不会很好地工作,因为
\uuuu init\uuuu
@ovgolovin中的参数不同,因为我是一个没有经验的程序员。我不知道什么是授权。我会尽力调查的。
class AB(object):
    def __init__(self, x, y, z=0):
        self.a = A(x,y)
        self.b = B(z)