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

Python子类对象调用父类__str__方法的问题及实现方案

Python面向对象中父类__str__调用问题解答

问题1:为何print(subclassObject.base())未自动调用父类__str__,反而返回对象描述?

super() 返回的不是父类的实例对象,而是super代理对象。这个代理的核心作用是协助调用父类的方法,但它本身不属于Orto类的实例。当你直接print这个super对象时,Python会调用super类自身的__str__方法,因此输出的是代理对象的描述信息,而非Orto类中定义的__str__返回值。只有显式调用c.__str__()时,super代理才会将该调用转发给父类Orto的__str__方法,从而得到预期结果。

问题2:需在类中定义什么内容,才能让print接收“降级为父类类型的子类对象”时默认调用父类__str__?

可以通过以下两种合理方式实现:

方式一:让base方法返回真正的父类实例

如果需求是获取独立的父类对象,可在base方法中创建并返回Orto实例:

class Rectangle(Orto):
    # 其他方法不变
    def base(self):
        return Orto()

注意:此方式会生成新的父类实例,与原Rectangle实例的状态无关。

方式二:自定义代理类,实现方法转发

如果需要保留原子类实例的状态,同时让代理对象在print时自动调用父类__str__,可以自定义代理类,将方法调用转发给父类:

class Rectangle(Orto):
    # 其他方法不变
    def base(self):
        class ParentProxy:
            def __init__(self, instance):
                self.instance = instance
            def __str__(self):
                return super(Rectangle, self.instance).__str__()
            def __getattr__(self, name):
                # 转发其他方法调用给父类
                return getattr(super(Rectangle, self.instance), name)
        return ParentProxy(self)

这样返回的代理对象,既会在print时自动调用父类__str__,也能正常调用父类的其他方法(如length)。


完整测试代码

class Orto():
    "General class"
    def __init__(self):
        "Initialise"
        print("Nothing, just init", end=" ")

    def __str__(self):
        "To string"
        return "To string"

    def length(self, _a, _b, _c, _d):
        "Count"
        return _a + _b + _c + _d


class Rectangle(Orto):
    "Rectangle case"
    def __init__(self):
        super().__init__()
        print("... and an rectangle")

    # 替换为上述任一base方法实现
    def base(self):
        class ParentProxy:
            def __init__(self, instance):
                self.instance = instance
            def __str__(self):
                return super(Rectangle, self.instance).__str__()
            def __getattr__(self, name):
                return getattr(super(Rectangle, self.instance), name)
        return ParentProxy(self)

    def __str__(self):
        return super().__str__() + " rectangle"

    def length(self, _a, _b):
        return super().length(_a, _b, _a, _b)


# 测试
o = Orto()
print(o, " ", o.length(2, 4, 2, 4))
# OUTPUT: Nothing, just init To string   12

r = Rectangle()
print(r, " ", r.length(3, 5))
# OUTPUT: Nothing, just init ... and an rectangle
#         To string rectangle   16

c = r.base()
print(c, " ", r.base().length(5, 5, 8, 5))
# 此时输出:To string   23

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:25:19