【问题标题】:Maximum recursion depth error in Python when calling super's init. [duplicate]调用 super 的 init 时 Python 中的最大递归深度错误。 [复制]
【发布时间】:2015-12-26 04:14:33
【问题描述】:

我有一个类层次结构 A 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 会自动填充参数)。

标签: python recursion hierarchy superclass


【解决方案1】:

首先要考虑: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 中的任何类的名称。事实上,您链接到的帖子中的第二个答案非常详细地介绍了这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 2021-10-05
    • 2021-12-11
    • 2011-01-24
    • 1970-01-01
    • 2014-05-08
    • 2012-12-22
    相关资源
    最近更新 更多