You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何带参数正确调用Python中的super()?

问题:super()带参数调用时的递归错误与正确用法

我有一个线性继承的类层次结构A、B、C,三者共享同名方法m,但方法的签名和类型(静态方法、类方法、实例方法)各不相同,子类的实现依赖父类方法的返回结果。因为需要动态创建对象,必须使用super()的完整签名调用,但这里出现了问题。

零参数super()可正常运行

class A:
    @staticmethod
    def m(): return 'A.m()'

class B(A):
    @classmethod
    def m(cls):
        return super().m() + ' ... & from B.m()'
    
class C(B):
    def m(self, text):
        return super().m() + f' ... & from C().m("{text}")'


print(C().m("XXX"))
# 输出:A.m() ... & from B.m() ... & from C().m("XXX")

带参数super()触发递归错误

当尝试使用完整签名的super()时,代码触发了RecursionError:

class A:
    @staticmethod
    def m(): return 'A.m()'

class B(A):
    @classmethod
    def m(cls):
        return super(cls, cls).m() + ' ... & from B.m()' # <- 触发RecursionError
    
class C(B):
    def m(self, text):
        return super(type(self), self).m() + f' ... & from C().m("{text}")'

print(C().m("XXX"))

报错信息:

File "path_to_file.py", line XY, in m
  return super(cls, cls).m() + ' ... & from B.m()'
         ^^^^^^^^^^^^^^^^^^^
[Previous line repeated 995 more times]
RecursionError: maximum recursion depth exceeded

抽象示例(同样问题)

class A:
    def m(self):
        return f"A().m from {type(self).__name__}()"
class B(A):
    def m(self):
        return super(?, ?).m() + f" & B().m from {type(self).__name__}()"
class C(B):
    def m(self):
        return super(type(self), self).m() + f" & C().m from {type(self).__name__}()"


print(C().m())
# 期望输出:A().m from C() & B().m from C() & C().m from C()

解决方法

核心原因

递归错误的本质是:使用super(cls, cls)(类方法中)或super(type(self), self)(实例方法中)时,第一个参数是当前对象/类的实际类型(可能是子类),导致super代理在MRO中跳过的是子类而非当前定义方法的类,最终循环调用当前方法。

正确写法

无论类方法还是实例方法,完整签名的super()第一个参数都应该写当前方法所在的类,而非动态获取的类型:

修复第一个示例

class A:
    @staticmethod
    def m(): return 'A.m()'

class B(A):
    @classmethod
    def m(cls):
        # 第一个参数写当前类B,而非动态的cls
        return super(B, cls).m() + ' ... & from B.m()'
    
class C(B):
    def m(self, text):
        # 第一个参数写当前类C,而非type(self)
        return super(C, self).m() + f' ... & from C().m("{text}")'

print(C().m("XXX"))
# 输出:A.m() ... & from B.m() ... & from C().m("XXX")

修复抽象示例

class A:
    def m(self):
        return f"A().m from {type(self).__name__}()"
class B(A):
    def m(self):
        return super(B, self).m() + f" & B().m from {type(self).__name__}()"
class C(B):
    def m(self):
        return super(C, self).m() + f" & C().m from {type(self).__name__}()"


print(C().m())
# 输出:A().m from C() & B().m from C() & C().m from C()

原理说明

  • 类方法中:super(B, cls)会在cls的MRO中跳过B,直接查找父类A的方法,避免因cls是子类(如C)导致的递归。
  • 实例方法中:super(C, self)会在self的MRO中跳过C,查找父类B的方法,即使后续出现C的子类,也不会触发递归。

内容的提问来源于stack exchange,提问作者cards

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 06:44:50