在子类中调用继承方法的区别?

时间:2011-02-24 05:21:45

标签: python

对于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()

3 个答案:

答案 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 }。