Dan*_*CDH 3 python inheritance multiple-inheritance diamond-problem python-3.x
考虑以下python代码:
class Parent(object):
def __init__(self, name, serial_number):
self.name = name
self.serial_number = serial_number
class ChildA(Parent):
def __init__(self, name, serial_number):
self.name = name
self.serial_number = serial_number
super(ChildA, self).__init__(name = self.name, serial_number = self.serial_number)
def speak(self):
print("I am from Child A")
class ChildB(Parent):
def __init__(self, name, serial_number):
self.name = name
self.serial_number = serial_number
super(ChildB, self).__init__(name = self.name, serial_number = self.serial_number)
def speak(self):
print("I am from Child B")
class GrandChild(ChildA, ChildB):
def __init__(self, a_name, b_name, a_serial_number, b_serial_number):
self.a_name = a_name
self.b_name = b_name
self.a_serial_number = a_serial_number
self.b_serial_number = b_serial_number
super(GrandChild, self).__init_( something )
Run Code Online (Sandbox Code Playgroud)
super
在GrandChild中运行该函数时,格式化__init__
参数的正确方法是什么,以使ChildA和ChildB都获得正确的参数?
您还如何speak
从GrandChild类中访问方法的两个不同版本(ChildA的版本和ChildB的版本)?
因此,当您从孙子代调用super时,将调用child a的__init__
方法,因为super跟随该__mro__
属性(父母从左到右,然后祖父母从左到右,然后是曾祖父母,...)
由于chaild a的init也调用超级,因此所有超级调用都将被链接,从而调用子b __init__
并最终调用父init。
为此,您的界面通常需要保持一致。也就是说,位置参数需要表示相同的意思,并且要有序。
在不是这种情况下,关键字参数可能会更好。
class Parent:
def __init__(self, name, serial, **kwargs):
self.name = name
self.serial = serial
class ChildA(Parent):
def __init__(self, a_name, a_serial, **kwargs):
self.a_name = a_name
self.a_serial = a_serial
super().__init__(**kwargs)
class ChildB(Parent):
def __init__(self, b_name, b_serial, **kwargs):
self.b_name = b_name
self.b_serial = b_serial
super().__init__(**kwargs)
class GrandChild(ChildA, ChildB):
def __init__(self):
super().__init__(name = "blah", a_name = "a blah", b_name = "b blah", a_serial = 99, b_serial = 99, serial = 30)
Run Code Online (Sandbox Code Playgroud)
还要注意,在您的代码名和序列号中,所有类之间的实例属性都被重用,这可能不是您想要的。