此代码抛出异常, 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()
答案 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()调用。)