Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 理解钻石继承中的super()_Python - Fatal编程技术网

Python 理解钻石继承中的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")

我正在学习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")
        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
vs
test
),这是一个很好的实践,可以查看
test
在各种超类组合中是否存在时是如何解析的

super()
是“从当前对象的超类调用给定方法”的显式请求


为了进一步阅读,搜索词“Python MRO”应该可以很好地为您服务,它可以引导您找到许多继承层次结构。

以下是您的继承层次结构:

除了有两个父类的
D
,您的大多数类都只继承一个父类。虽然未明确说明,
A
隐式继承自
对象

对于任何类的对象,请按照图向后到根的方向查看Python检查类以查找调用的方法的顺序。例如,将按
D
B
C
A
对象的顺序访问
D
实例。这里
B
C
之前,因为它在类定义中列在第一位

看起来您已经稍微改变了方法名称(
test2
vs
test
),这是一个很好的实践,可以查看
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,您将从中获得输出,然后是之前的输出。不确定此键入是否是故意的:您将方法命名为类D
test2()
,而不是
test()
因此它将被覆盖。不确定此键入是否是故意的:您在类D
test2()
中命名了该方法,而不是
test()
因此它将被覆盖。