用不同的参数在python中调用超类构造函数
如何使AB的构造函数使用正确的参数调用A和B的构造函数 我试过了用不同的参数在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): ? 但这给了我一个错误。您
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)