调用重写方法,超类调用重写方法

时间:2011-10-22 12:44:01

标签: python inheritance superclass

此代码抛出异常, AttributeError,“wtf!”,因为A.foo()正在调用B.foo1(),是否应该调用A.foo1()?如何强制它拨打A.foo1()A.foo()内的任何方法调用都应拨打A.*

class A(object):
    def foo(self):
        print self.foo1()

    def foo1(self):
        return "foo"

class B(A):
    def foo1(self):
        raise AttributeError, "wtf!"

    def foo(self):
        raise AttributeError, "wtf!"

    def foo2(self):
        super(B, self).foo()

myB = B()
myB.foo2()

4 个答案:

答案 0 :(得分:8)

在A级而不是调用self方法时,您需要调用A方法并手动传入self

这不是正常的做事方式 - 你应该有一个真的这样做的理由。

class A(object):
    def foo(self):
        print A.foo1(self)

    def foo1(self):
        return "foo"

class B(A):
    def foo1(self):
        raise AttributeError, "wtf!"

    def foo(self):
        raise AttributeError, "wtf!"

    def foo2(self):
        super(B, self).foo()

myB = B()
myB.foo2()

答案 1 :(得分:6)

它按预期工作,因为100%的世界编程语言都有效。子类重写父类的所有方法。

但是如果你真的想要调用A.foo1(),你可能会这样做(我无法保证)。无论如何你不能这样做,因为这违背了良好编程的所有原则。

 class A(object):

    def foo(self):
        A.foo1(self)

答案 2 :(得分:4)

在代码中:

def foo2(self):
    super(B, self).foo()

self是B的一个实例。

当一个派生自A的方法被B的实例调用时,它将开始从B中查找命名空间,并且只有在找不到该方法时(例如,未被B覆盖),才使用A的实现,但是总是自我指的是B.在任何时候,自我都不是A的实例。

答案 3 :(得分:-1)

可以看到Python在这里做了什么,但是覆盖的方式有点极端。假设A类定义100个属性,B类继承这些属性并再添加1个属性。我们希望能够让__init __()为B调用A的__init __(),让B的代码只定义它的单个属性。类似地,如果我们在A中定义一个reset()方法将所有属性设置为零,那么B的相应reset()方法应该只能为A调用reset()方法,然后将单个B属性归零。必须复制所有A的代码。 Python正在变得困难,这应该是面向对象编程的一个主要优势;也就是说,代码的重用。这里最好的选择是避免覆盖我们真正想要重用的方法。如果您想在这里了解Python的复杂性,请尝试以下代码:

class X(object):
    def __init__ ( self ):
        print "X"
        self.x = 'x'
        self.reset()
        print "back to X"
    def reset ( self ):
        print "reset X"
        self.xx = 'xx'

class Y(X):
    def __init__ ( self ):
        print "Y"
        super(Y,self).__init__()
        self.y = 'y'
        self.reset()
        print "back to Y"
    def reset ( self ):
        print "reset Y"
        super(Y,self).reset()
        print "back to reset Y"
        self.yy = 'yy'

aY = Y()

(为了使其正常工作,请删除__init __()中针对Y类的self.reset()调用。)