对于Python 2.5及更高版本,使用新的样式类,以下代码片段在子类中调用继承方法的区别是什么?
class A(object):
def foo(self):
pass
class B(A):
def __init__(self):
self.foo()
class C(A):
def __init__(self):
super(C, self).foo()
答案 0 :(得分:1)
只要您处理单个继承类,就像您给出的示例一样,
没有太大区别。在任何一种情况下,python都使用方法解析顺序(mro),
(您可以通过打印C.__mro__
来检查)以找出该方法的第一次出现
FOO。这些都解析为你的基类,A的,foo实现。
然而,当你有多个继承时,事情变得有趣。请看以下内容 例如:
class W(object):
def foo(self):
print "W"
class X(W):
def foo(self):
#super(X,self).foo()
W.foo(self)
print "X"
class Y(W):
def foo(self):
print "Y"
class Z(X,Y):
def __init__(self):
self.foo()
Z.__mro__
z = Z()
如果你看一下X类,我们可以使用super来调用X的基类,或者我们 可以使用直接调用基类W.不同的是,当使用super时,python 不寻找具体的实现,而是寻找第一个实现 目前的mro清单。 Z的mro列表是:
(Z,X,Y,W)
因此,使用super的那个将打印:
Y
X
而直接调用基地的那个将打印:
W
X
基本上,使用super动态调用mro中第一个找到的实现,而class.foo(或者在你的情况下是self.foo)调用该特定方法。
答案 1 :(得分:0)
不同之处在于B
的后代可以正确地参与多态,因为如果被覆盖则会调用foo()
方法,而C
没有此选项。
答案 2 :(得分:0)
假设B
本身定义了foo
方法,则self.foo()
会调用B
的{{1}}版本。通过foo
的实施,C
调用可确保调用super
的{{1}}版本,即使A
也定义foo
}。