python3 - super()对多继承的行为 [英] python3 - behaviour of super() on multi-inheritance

查看:253
本文介绍了python3 - super()对多继承的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这里已经讨论过super()和多继承。但我没有找到解决方案,关于我在python3中的具体问题。
假设我们有:

I know that super() and multi-inheritance have already been discussed here. But I did not find a solution, regarding my specific problem in python3. Let's assume we have:

#! /usr/bin/env python3

class A(object):
    def __init__(self):
        super().__init__()

    def foo(self):
        print("The")

class B(object):
    def __init__(self):
        super().__init__()

    def foo(self):
        print("world")

class C(B):
    def __init__(self):
        super().__init__()

    def foo(self):
        super().foo()
        print("is")

class D(A,C):
    def __init__(self):
        super().__init__()

    def foo(self):
        super().foo()
        print("nice")

d = D()

d.foo()

这会让我:

The
nice

另一方面,如果我改变D中的继承顺序( )到:

On the other hand, if I change the order of inheritance in D() to:

class D(C,A):
    def __init__(self):
        super().__init__()

    def foo(self):
        super().foo()
        print("nice")

它给了我

world
is
nice

然而,我只获得所需的输出:

I, however, only get the desired output:

The
world
is
nice

使用:

class D(C,A):
    def __init__(self):
        super().__init__()

    def foo(self):
        A.foo(self)
        C.foo(self)
        print("nice")

我发现它非常不优雅。

所以我的问题是:是否可以在python3中使用super()来调用两个超类的超级方法而不仅仅是第一个?

So my question is: Is it possible to use super() in python3 invoking the super method of both super classes instead of just the first?

推荐答案

不幸的是,如果不知道 D 的方法解析顺序(MRO),就无法调用 super() D 中获取两个基类。

Unfortunately, without a knowledge of the method resolution order (MRO) of D, there is no way to call super() in D to get at both base classes.

但是MRO是一个强大的概念。在第二种情况下,

But the MRO is powerful concept. In the second case,

class D(C,A):
    ...

(MRO)

>>> D.mro()
[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]

因为调用 super()将您带到MRO的下一个班级,正如Pieters先生所说,并且您希望打印语句的顺序为 A B C ,然后 D ,只需在<$ c的每个定义中首先放置 super()。foo()并且 print(...)秒$ C> FOO()。唯一的例外是不要在类 A 中放入 super()。foo(),因为 foo()未在对象中定义。

Inasmuch as calling super() takes you to the next class in the MRO, as Mr. Pieters stated, and you want the print statements coming in the order of A, B, C, then D, simply put super().foo() first and print(...) second in each definition of foo(). The only exception is do not put super().foo() in class A because foo() is not defined in object.

#! /usr/bin/env python3

class A(object):
    def __init__(self):
        super().__init__()

    def foo(self):
        print("The")

class B(object):
    def __init__(self):
        super().__init__()

    def foo(self):
        super().foo()      # Inserted
        print("world")

class C(B):
    def __init__(self):
        super().__init__()

    def foo(self):
        super().foo()
        print("is")

class D(C,A):              # Correct ordering
    def __init__(self):
        super().__init__()

    def foo(self):
        super().foo()
        print("nice")

d = D()

d.foo()



替代解决方案



第一种情况下的 D(A,C)的MRO也包括所有类,所以正确排序 super() print(...)声明s,一个可以使它工作:

Alternate solution

The MRO of D(A,C) in the first case includes all classes as well, so with correct ordering of super() and print(...) statements, one can make it work:

class A(object):
    def foo(self):
        print("The")
        super().foo()

class B(object):
    def foo(self):
        print("world")

class C(B):
    def foo(self):
        super().foo()
        print("is")

class D(A,C):
    def foo(self):
        super().foo()
        print("nice")

D().foo()



进一步阅读



了解继承顺序(例如 D类(C,A) D类(A,C))和MRO,见 https://www.python.org/download/releases/2.3/mro/ 。详细描述了C3方法的分辨率顺序,并且有很好的绘制的ASCII类层次结构,标有MRO。

Further reading

To understand inheritance order (e.g. class D(C,A) or class D(A,C)) and MRO, see https://www.python.org/download/releases/2.3/mro/. The C3 method resolution order is described in detail and there are nicely drawn ASCII class hierarchies with the MRO labeled.

这篇关于python3 - super()对多继承的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆