我可以帮您翻译成中文。以下是翻译的结果,保留了HTML标签。
所以
如果您正确理解Python的继承机制和
编辑:根据Daniel Roseman的答案,我尝试用以下形式替换
我有一个三层继承链:Baz 继承自 Bar,Bar 继承自 Foo。我想在 Foo 类中定义一个方法,在其子类中调用时,返回其父类的输出加上自己的内容。这是期望的输出:
>>> foo = Foo()
>>> bar = Bar()
>>> baz = Baz()
>>> print foo.get_defining_fields()
['in Foo']
>>> print bar.get_defining_fields()
['in Foo', 'in Bar']
>>> print baz.get_defining_fields()
['in Foo', 'in Bar', 'in Baz']
问题在于,我对于在子类中调用超类方法时使用super()
的细节或其他继承细节存在误解。以下部分是正确的:
>>> print foo.get_defining_fields()
['in Foo']
但是bar.get_defining_fields()
会产生一个无限循环,一直运行自己,直到抛出RuntimeError
,而不是像我想要的那样调用foo.get_defining_fields
并在那里停止。
这是代码。
class Foo(object):
def _defining_fields(self):
return ['in Foo']
def get_defining_fields(self):
if self.__class__ == Foo:
# Top of the chain, don't call super()
return self._defining_fields()
return super(self.__class__, self).get_defining_fields() + self._defining_fields()
class Bar(Foo):
def _defining_fields(self):
return ['in Bar']
class Baz(Bar):
def _defining_fields(self):
return ['in Baz']
所以
get_defining_fields
在超类中定义,它内部的super()
调用使用self.__class__
来尝试在每个子类中传递正确的子类名。 当在Bar中调用时,它会解析为super(Bar, self).get_defining_fields()
,以便由foo.get_defining_fields()
返回的列表将被预置到由far.get_defining_fields()
返回的列表之前。如果您正确理解Python的继承机制和
super()
的内部工作原理,那么这可能是一个简单的错误,但由于我显然不懂,所以如果有人能指出正确的方法,我将不胜感激。编辑:根据Daniel Roseman的答案,我尝试用以下形式替换
super()
调用:return super(Foo, self).get_defining_fields() + self._defining_fields()
现在无限递归不再发生,但在调用bar.get_defining_fields()
时出现了不同的错误。AttributeError: 'super' object has no attribute 'get_defining_fields'
还有一些问题没有解决。
编辑: 是的,最终我弄清楚了这里缺少什么。将 Daniel 更新的答案标记为已采纳。