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

如何在子类重写的方法中使用返回实例的父类classmethod?

问题:子类调用父类classmethod时,如何让父类方法返回父类实例?

我使用Python 3.9,现有一个父类的classmethod会返回该类的实例。我希望在子类中调用父类的这个classmethod,同时返回子类的实例。示例代码如下:

class A:
    def __init__(self, s):
        print("init in class A")
        self.s = s
    
    @classmethod
    def f(cls, s):
        print("f in class A")
        return cls(s)

class B(A):
    def __init__(self, s):
        print("init in class B")
        super().__init__(s)

    @classmethod
    def f(cls, s):
        print("f in class B")
        a = A.f(s)
        # a = super(B, cls).f(s)
        # a = super().f(s)
        s = "class B " + a.s
        return cls(s)

当使用A.f(s)时,输出结果符合预期:

>>> B.f("toto").s 
f in class B
f in class A
init in class A
init in class B
init in class A

'class B toto'

但如果取消子类B中classmethod f里任意一行注释(比如super(B, cls).f(s)),输出变为:

>>> B.f("toto").s 
f in class B
f in class A
init in class B
init in class A
init in class B
init in class A

'class B toto'

结果正确,但我不理解为何父类A的classmethod会先调用B的__init__方法?我感觉此时父类classmethod中的cls仍指向子类B,不知道如何修改才能让cls指向A。


原因分析

当你用super(B, cls).f(s)或者super().f(s)调用父类的f方法时,传递给A.f的cls参数其实是子类B。因为调用B.f("toto")时,B.f内部的cls就是B,super的作用只是帮你找到父类A的f方法,但调用这个方法时,cls参数并不会被替换成A,还是保持原来的B。所以A.f里执行return cls(s)时,实际创建的是B的实例,自然会先触发B的__init__。

解决方案

如果你想让父类的f方法返回A的实例,直接用A.f(s)就可以——这就是你最初的写法,显式调用A的类方法时,A.f内部的cls就是A,创建的是A的实例,只会触发A的__init__,完全符合你的需求。

不需要用super来调用这个父类方法,因为你的目标就是获取父类的实例,直接调用父类的类方法是最直接且清晰的实现方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:27:30