关于 super() 方法的困惑
Puzzle about super() method
我正在尝试了解 super()
方法的工作原理。这是我使用的示例代码:
class A(object):
def __init__(self):
self.n = 'A'
def func(self):
print('@A')
self.n += 'A'
class B(A):
def __init__(self):
self.n = 'B'
def func(self):
print('@B')
self.n += 'B'
class C(A):
def __init__(self):
self.n = 'C'
def func(self):
print('@C')
super().func()
self.n += 'C'
class D(C, B):
def __init__(self):
self.n = 'D'
def func(self):
print('@D')
super().func()
self.n += 'D'
print(D.mro())
d = D()
d.func()
print(d.n)
正确的输出结果是:
[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
DBCD
我不明白的是为什么输出中没有A
?我以为在进入Class C时,有一个super().func()
调用了Class A中的func
。然而,事实并非如此。
谁能帮我理解这种行为?
谢谢!
super().func
不是父级的 func
方法——它是 MRO 中下一个 class 的方法。没有出现A
是因为B
的func
没有调用super().func
,所以链停在B
.
不,每个 super().func()
调用都允许您在 的下一个 class 中调用 func
self
的 MRO(这可能与当前 class 的 MRO 不同)。当您在 D
的实例上调用 C.func
时,您遵循 D
的 MRO 并看到在 C
之后出现 B
.
B.func
不调用 super
,因此链在那里结束,跳过 A
。如果您希望 B.func
在多重继承情况下可用,它也需要调用 super().func()
,就像其他 classes 一样。
super
不只是调用父 class。它确保以正确的顺序调用多重继承树中的 classes。
在你的例子中,D 中的 super
调用了 C。C 中的 super
调用了 B,但是因为 B 没有调用 super
,链中断了下来。
我正在尝试了解 super()
方法的工作原理。这是我使用的示例代码:
class A(object):
def __init__(self):
self.n = 'A'
def func(self):
print('@A')
self.n += 'A'
class B(A):
def __init__(self):
self.n = 'B'
def func(self):
print('@B')
self.n += 'B'
class C(A):
def __init__(self):
self.n = 'C'
def func(self):
print('@C')
super().func()
self.n += 'C'
class D(C, B):
def __init__(self):
self.n = 'D'
def func(self):
print('@D')
super().func()
self.n += 'D'
print(D.mro())
d = D()
d.func()
print(d.n)
正确的输出结果是:
[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
DBCD
我不明白的是为什么输出中没有A
?我以为在进入Class C时,有一个super().func()
调用了Class A中的func
。然而,事实并非如此。
谁能帮我理解这种行为?
谢谢!
super().func
不是父级的 func
方法——它是 MRO 中下一个 class 的方法。没有出现A
是因为B
的func
没有调用super().func
,所以链停在B
.
不,每个 super().func()
调用都允许您在 的下一个 class 中调用 func
self
的 MRO(这可能与当前 class 的 MRO 不同)。当您在 D
的实例上调用 C.func
时,您遵循 D
的 MRO 并看到在 C
之后出现 B
.
B.func
不调用 super
,因此链在那里结束,跳过 A
。如果您希望 B.func
在多重继承情况下可用,它也需要调用 super().func()
,就像其他 classes 一样。
super
不只是调用父 class。它确保以正确的顺序调用多重继承树中的 classes。
在你的例子中,D 中的 super
调用了 C。C 中的 super
调用了 B,但是因为 B 没有调用 super
,链中断了下来。