如何从两个父类中调用“重写”方法?

问题描述 投票:1回答:1

请考虑以下类,其中P1P2C的父类:

class P1:
    def f(self):
        print('P1')


class P2:
    def f(self):
        print('P2')


class C(P1, P2):
    def f(self):
        print('C')
        # super().f()
        # super(P1, self).f()

c = C()
c.f()

当我运行此命令时,它打印C

如果我取消注释第一行super().f(),那么它也会打印P1因为super()将从直接父级调用该方法,所以P1

如果我取消注释第二行super(P1, self).f(),那么它也会打印P2因为super(P1, self)将从P1的同级中调用该方法,所以P2

[我想知道的是,是否有任何方法可以通过一次调用f函数从两个父类P1P2中调用super()方法,而不是像我一样两次调用它。做到了。

或者,是否有其他方法可以不使用super功能呢?

python python-3.x overriding multiple-inheritance super
1个回答
0
投票

没有很好的方法来精确地完成您想要的。但是,如果您可以同时修改P1P2,则可以实现协作式多重继承,您只需要向具有该方法的no-op实现的两个父类中添加一个基类:

class GP: # grandparent base class
    def f(self):
        pass  # do nothing

class P1(GP):
    def f(self):
        print("P1")
        super().f()

class P2(GP):
    def f(self):
        print("P2")
        super().f()

class C(P1, P2):
    def f(self):
        print("C")
        super().f()

这是有效的,因为super并不完全意味着“我的父母班级”。它的意思是“该对象的MRO中的下一个”。 MRO是方法解析顺序,基本上是在继承中搜索事物的顺序。在super()中调用C时,它将在P1中找到方法。但是,当在super()上(在P1的实例上)调用C时,它会调用P2,因为C实例的MRO为[C, P1, P2, GP, object]P2紧随P1之后,因此被第二个super调用选择。

GP类是结束super调用链所必需的。如果没有它,最后一个super调用将解析为object(这是所有继承树的根),并且由于没有这样的方法,您会得到一个错误。基类中的实现不需要执行任何操作,只需要最后不调用super

© www.soinside.com 2019 - 2024. All rights reserved.