假设我有一个多重继承的场景:
class A(object):
# code for A here
class B(object):
# code for B here
class C(A, B):
def __init__(self):
# What's the right code to write here to ensure
# A.__init__ and B.__init__ get called?
有两种典型的方法来编写C语言的__init__:
(老式)ParentClass.__init__(自我)
(new -style) super(DerivedClass, self).__init__()
然而,在任何一种情况下,如果父类(A和B)不遵循相同的约定,那么代码将不能正确工作(有些可能会丢失,或被多次调用)。
正确的方法是什么来着?说“保持一致,遵循其中一个”很容易,但如果A或B来自第三方库,那怎么办?是否有一种方法可以确保所有父类构造函数都被调用(并且以正确的顺序,并且只调用一次)?
编辑:看看我的意思,如果我这样做:
class A(object):
def __init__(self):
print("Entering A")
super(A, self).__init__()
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
A.__init__(self)
B.__init__(self)
print("Leaving C")
然后我得到:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
注意B的init被调用了两次。如果我这样做:
class A(object):
def __init__(self):
print("Entering A")
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
super(C, self).__init__()
print("Leaving C")
然后我得到:
Entering C
Entering A
Leaving A
Leaving C
注意B的init从未被调用。因此,似乎除非我知道/控制从(A和B)继承的类的初始化,否则我无法为我正在编写的类(C)做出安全的选择。
下面是我如何在Python 3中使用super()实现多重继承
class A:
def __init__(self, a, b, **kwargs):
print("Class A initiallised")
self.a = a
self.b = b
super().__init__(**kwargs)
print("Class A initiallisation done")
def __str__(self):
return f"{self.a} and {self.b}"
def display_a(self):
return f"{self.a} and {self.b}"
class C:
def __init__(self, c, d, **kwargs):
print("Class C initiallised")
self.c = c
self.d = d
super().__init__(**kwargs)
print("class c initiallisation done")
def __str__(self):
return f"{self.c} and {self.d}"
def display_c(self):
return f"{self.c} and {self.d}"
class D(A,C):
def __init__(self, e, **kwargs):
print("Class D initiallised")
super().__init__(**kwargs)
self.e = e
print("Class D initiallisation done")
def __str__(self):
return f"{self.e} is e,{self.b} is b,{self.a} is a,{self.d} is d,{self.c} is c"
if __name__ == "__main__":
d = D(a=12, b=13, c=14, d=15, e=16)
print(d)
d.display_c()
d.display_a()
下面是我如何在Python 3中使用super()实现多重继承
class A:
def __init__(self, a, b, **kwargs):
print("Class A initiallised")
self.a = a
self.b = b
super().__init__(**kwargs)
print("Class A initiallisation done")
def __str__(self):
return f"{self.a} and {self.b}"
def display_a(self):
return f"{self.a} and {self.b}"
class C:
def __init__(self, c, d, **kwargs):
print("Class C initiallised")
self.c = c
self.d = d
super().__init__(**kwargs)
print("class c initiallisation done")
def __str__(self):
return f"{self.c} and {self.d}"
def display_c(self):
return f"{self.c} and {self.d}"
class D(A,C):
def __init__(self, e, **kwargs):
print("Class D initiallised")
super().__init__(**kwargs)
self.e = e
print("Class D initiallisation done")
def __str__(self):
return f"{self.e} is e,{self.b} is b,{self.a} is a,{self.d} is d,{self.c} is c"
if __name__ == "__main__":
d = D(a=12, b=13, c=14, d=15, e=16)
print(d)
d.display_c()
d.display_a()