在Python中,为什么为未定义超类的类调用super()函数不是错误?

在Python中,为什么为未定义超类的类调用super()函数不是错误?,python,Python,对于一个Python新手,有人能告诉我这里发生了什么吗?为什么要打印“初始化” 如果我从类B的\uuuuu init\uuuu函数中删除行super()。\uuuuuu init\uuuuuu(),则行为与预期一样。但是为什么下面的代码不是错误,我想B不会有超类 class A: def __init__(self): print("A init") class B: def __init__(self): super().__init__(

对于一个Python新手,有人能告诉我这里发生了什么吗?为什么要打印“初始化”

如果我从类
B
\uuuuu init\uuuu
函数中删除行
super()。\uuuuuu init\uuuuuu()
,则行为与预期一样。但是为什么下面的代码不是错误,我想
B
不会有超类

class A:

    def __init__(self):
        print("A init")

class B:

    def __init__(self):
        super().__init__()   # why is this line not an error
        print("B init")

class C(B, A):

    def __init__(self):
        super().__init__()
        print("C init")

c = C()
输出
您创建了一个
C
的实例,我们称之为
self
。它的MRO为
C
B
A
对象

C
\uuuu init\uuuu
第一次调用
super()。\uuuu init\uuuu()
。这将使用相同的
self
对象,委托给MRO中下一个类中的
\uuuuuuuuuuuuuuuuuuuuuuuuuuu
,即B

B
\uuuu init\uuu
首先调用
super()。这将委托给
self
类(
C
)的MRO中下一个类中的
\uuuuuuuuu init\uuuuuuuu
),即
A

A
\uuuuu init\uuu
打印并返回到
B
\uuu init\uu

B
's
\uuuu init\uuu
打印并返回到
C
's
\uu init\uuu

C
\uuuuuu init\uuuuuuuuuuu
打印并返回到构造函数(
对象的
\uuuu new\uuuuuuuuu
),该构造函数返回
self

super()
有两个隐藏参数,
\uuuuu class\uuuuuu
(因此它知道在MRO中从何处开始),和
self
(或者
cls
,对于
@classmethod
而言,不管第一个参数是什么,都是


您必须在Python2中显式地提供它们(现在仍然可以),但是在Python3中
super()。(
\uuu class\uu
变量在方法中是隐式可用的,并且是在其中定义它的类。)

在Python3中,所有类都继承自
对象。但是当我调用C的构造函数时,为什么它要打印“A init”,我在想,按照MRO规则,它只会打印“B init”,因为它解析为“最左边的类”?B的init函数似乎在调用A的init函数。我认为C同时调用A和B,多重继承。根据我的理解,C应该调用它自己的init函数,如果定义的话。在我的代码中,当我在C的init中调用init of super()时,它应该调用B的init,因为B是按优先级排列的“超类”(最左边),因为C被定义为C(B,A)。顺便说一句,你可以使用这个在线工具来可视化代码执行
A init

B init

C init

Process finished with exit code 0