Python 理解钻石继承中的super()
我正在学习python,并开始学习继承中的MRO 我已经阅读了super的用法以及它的使用方法,但是我不能将我的理解放在下面的问题上。如果它不是超级的,我知道它叫B。D->B->C->A但是当super被添加时,我不知道为什么输出是这样的Python 理解钻石继承中的super(),python,Python,我正在学习python,并开始学习继承中的MRO 我已经阅读了super的用法以及它的使用方法,但是我不能将我的理解放在下面的问题上。如果它不是超级的,我知道它叫B。D->B->C->A但是当super被添加时,我不知道为什么输出是这样的 class A: def test(self): print("test of A called") class B(A): def test(self): print("test of B called")
class A:
def test(self):
print("test of A called")
class B(A):
def test(self):
print("test of B called")
super().test()
class C(A):
def test(self):
print("test of C called")
super().test()
class D(B, C):
def test2(self):
print("test of D called")
obj=D()
obj.test()
输出
test of B called
test of C called
test of A called
请帮助我理解super在这里是如何工作的。super()
将按照Python遵循C3 linerization()的方法解析顺序转到下一个类:子类在其父类之前被调用,多个父类按其设置顺序被调用
因此,如果您在类D中调用一个方法,MRO是D->B->C->a,但例如,如果您最初在类B中调用它,MRO是B->a
这是否更清楚
编辑:在您的示例中:
您调用不存在的D.test()
,因此它被委托给B.test()
,后者打印一个字符串,然后调用super()
。由于如上所述的MRO,在本例中,B的super()
是C,因此调用C.test()
,然后调用A.test()
,super()
将按照Python遵循C3行化():在调用其父级之前调用子级,并按设置顺序调用多个父级
因此,如果您在类D中调用一个方法,MRO是D->B->C->a,但例如,如果您最初在类B中调用它,MRO是B->a
这是否更清楚
编辑:在您的示例中:
您调用不存在的
D.test()
,因此它被委托给B.test()
,后者打印一个字符串,然后调用super()
。由于如上所述的MRO,在本例中,B的super()
是C,因此下一步调用C.test()
,最后调用A.test()
这是您的继承层次结构:
除了有两个父类的D
,您的大多数类都只继承一个父类。虽然未明确说明,A
隐式继承自对象
对于任何类的对象,请按照图向后到根的方向查看Python检查类以查找调用的方法的顺序。例如,将按D
、B
、C
、A
、对象的顺序访问D
实例。这里B
在C
之前,因为它在类定义中列在第一位
看起来您已经稍微改变了方法名称(test2
vstest
),这是一个很好的实践,可以查看test
在各种超类组合中是否存在时是如何解析的
super()
是“从当前对象的超类调用给定方法”的显式请求
为了进一步阅读,搜索词“Python MRO”应该可以很好地为您服务,它可以引导您找到许多继承层次结构。以下是您的继承层次结构:
除了有两个父类的D
,您的大多数类都只继承一个父类。虽然未明确说明,A
隐式继承自对象
对于任何类的对象,请按照图向后到根的方向查看Python检查类以查找调用的方法的顺序。例如,将按D
、B
、C
、A
、对象的顺序访问D
实例。这里B
在C
之前,因为它在类定义中列在第一位
看起来您已经稍微改变了方法名称(test2
vstest
),这是一个很好的实践,可以查看test
在各种超类组合中是否存在时是如何解析的
super()
是“从当前对象的超类调用给定方法”的显式请求
为了进一步阅读,搜索词“PythonMRO”应该可以很好地为您服务,它会引导您找到许多。那么这是否意味着super也遵循MRO方法,并在D->B->C->a中打印所有测试?如果我有super,那也会遵循相同的顺序?它会按照这个顺序打印所有的测试方法?基本上,你可以把super()
看作是指MRO中的下一个类。是的,如果您将D中的test2()
重命名为test()
,并从中调用super,您将从中获得输出,然后是之前的输出。那么这是否意味着super也遵循MRO方法,并在D->B->C->A中打印所有测试?如果我有super,那也会遵循相同的顺序?它会按照这个顺序打印所有的测试方法?基本上,你可以把super()
看作是指MRO中的下一个类。是的,如果您将D中的test2()
重命名为test()
,并从中调用super,您将从中获得输出,然后是之前的输出。不确定此键入是否是故意的:您将方法命名为类Dtest2()
,而不是test()
因此它将被覆盖。不确定此键入是否是故意的:您在类Dtest2()
中命名了该方法,而不是test()
因此它将被覆盖。