调用super的init时在Python中出现了最大递归深度错误。

13

我有一个类的层次结构A <- B <- C,在B中,我需要在构造函数中进行一些处理,因此我从这篇文章中得出了以下代码:Understanding Python super() with __init__() methods

#!/usr/bin/python

class A(object):
    def __init__(self, v, v2):
        self.v = v
        self.v2 = v2

class B(A):
    def __init__(self, v, v2):
        # Do some processing
        super(self.__class__, self).__init__(v, v2)

class C(B):
    def hello():
        print v, v2


b = B(3, 5)
print b.v
print b.v2

c = C(1,2)
print c

然而,我遇到了一个“最大递归深度超过”的运行时错误。

  File "evenmore.py", line 12, in __init__
    super(self.__class__, self).__init__(v, v2)
RuntimeError: maximum recursion depth exceeded while calling a Python object

可能出了什么问题?


或者如果您能够使用Python 3,只需使用super()(Python 3会自动填充参数)。 - ShadowRanger
2个回答

9

需要考虑的第一件事:C类从B类继承构造函数(因为在C类中未定义)。

需要考虑的第二件事: 在C类的__init__调用中,self.__class__是C而不是B。

让我们分析一下:

  • C().__init__调用super(self.__class__, self).__init__(v, v2),这被解析为 super(C, self).__init__(v, v2),这意味着B.__init__(self, v, v2)
  • 传递给B.__init__的第一个参数的类型为Csuper(self.__class__, self).__init__(v, v2)再次被解析为B.__init__(self, v, v2)
  • 再一次,再一次,再一次。这就是无限递归的原因。

2
将super的第一个参数指定为类名可以解决这个问题。
class B(A):
    def __init__(self, v, v2):
        # Do some processing
        super(B, self).__init__(v, v2)

应该很清楚为什么; self.__class__ 总是具体类,而不是您在MRO中所在的任何类的名称。实际上,您链接到的帖子中的第二个答案详细介绍了这一点。 - Daniel Roseman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接