在 Python 中,为啥为没有定义超类的类调用 super() 函数不是错误? [复制]
Posted
技术标签:
【中文标题】在 Python 中,为啥为没有定义超类的类调用 super() 函数不是错误? [复制]【英文标题】:In Python why is calling super() function for a class with no superclass defined is not an error? [duplicate]在 Python 中,为什么为没有定义超类的类调用 super() 函数不是错误? [复制] 【发布时间】:2019-11-05 19:38:10 【问题描述】:对于 Python 新手,谁能告诉我这里发生了什么?为什么要打印“A init”?
如果我从__init__
类B
的函数中删除super().__init__()
行,则行为符合预期。但是为什么下面的代码没有错误,我虽然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()
输出
A init
B init
C init
Process finished with exit code 0
【问题讨论】:
在python 3中所有类都继承自object
。
我明白了。但是当我调用 C 的构造函数时,为什么它打印“A init”,我在想根据 MRO 规则它只会打印“B init”,因为它解析为“最左边的类”?看来 B 的 init 函数正在调用 A 的 init 函数。
我认为C同时调用A和B,多重继承
嗯。根据我的理解,C 应该调用它自己的 init 函数(如果已定义),并且在我的代码中,当我在 C 的 init 中调用 super() 的 init 时,它应该调用 B 的 init,因为 B 是优先级的“超类”(最左边) 因为它 C 被定义为 C(B,A)
顺便说一句,你可以使用这个在线工具来可视化代码执行pythontutor.com/visualize.html#mode=edit
【参考方案1】:
您创建一个C
的实例,我们将其称为self
。它的 MRO 为 C
、B
、A
、object
。
C
的__init__
首次调用super().__init__()
。这将委托给 MRO 中下一个类(即 B)中的 __init__
,使用相同的 self
对象。
B
的__init__
第一次调用super().__init__()
。这将委托给 self
的类 (C
) 的 MRO 中的下一个类中的 __init__
,即 A
。
A
's __init__
打印并返回到B
's __init__
。
B
's __init__
打印并返回到C
's __init__
。
C
's __init__
打印并返回到构造函数(object
's __new__
),它返回self
。
super()
有两个隐藏参数,__class__
(因此它知道在 MRO 中从哪里开始)和self
(或cls
,对于@classmethod
s——不管第一个参数是什么,不管名字)。
您必须在 Python 2 中显式提供这些(并且仍然可以),但在 Python 3 中 super()
实际上会检查其调用者的堆栈帧,并在从方法内部调用时找到这些。 (__class__
变量在方法中隐式可用,并且是定义它的类。)
【讨论】:
以上是关于在 Python 中,为啥为没有定义超类的类调用 super() 函数不是错误? [复制]的主要内容,如果未能解决你的问题,请参考以下文章