python中多继承的动态super()

Dynamic super() in multi-inheritance in Python

我有这样的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class X(object):
    def __init__(self):
        print('X')
    def Print(self):
        print('X')


class Y(object):
    def __init__(self):
        print('Y')
    def Print(self):
        print('Y')

class Z(X,Y):
    def __init__(self):
        print('Z')
        def Print(self):
            print('z')
            super().Print()

>>> z=Z()
Z
>>> z.Print()
X

它根据

1
2
Z.__mro__
(<class '__main__.Z'>, <class '__main__.X'>, <class '__main__.Y'>, <class 'object'>)

在江户第一次发现。但是如果我想运行z.Print()运行Y.Print(),我可以使用一个明确的类名,比如:

1
2
3
4
5
6
class Z(X,Y):
    def __init__(self):
        print('Z')
        def Print(self):
            print('z')
            Y.Print()

但这不是动态的。有更好的方法吗?


我真的要看你想做什么。如果要确保同时调用X.PrintY.Print,则需要在X.PrintY.Print中添加超级调用,以及具有占位符打印方法的基类。

如果您想根据某些条件调用X.PrintY.Print,那么继承可能是您的错误模型。你可以试着用作文。在这里,您编写的类不是继承自XY,而是将它们的实例作为成员并知道如何使用它们。如。

遗传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from abc import abstractmethod, ABCMeta

class Base(metaclass=ABCMeta):
    @abstractmethod
    def Print(self):
        pass

class X(Base):
    def Print(self):
        print("X")
        super().Print()

class Y(Base):
    def Print(self):
        print("Y")
        super().Print()

class Inheritance(X, Y):
    def Print(self):
        print("Inheiritance")
        super().Print()

Inheritance().Print()

输出:

1
2
3
Inheiritance
X
Y

作文

1
2
3
4
5
6
7
8
9
10
class Composition:
    def __init__(self):
        self.x = X()
        self.y = Y()
    def Print(self):
        print("Composition")
        self.x.Print()
        self.y.Print()

Composition().Print()

输出:

1
2
3
Composition
X
Y


为便于将来参考,以下是评论中讨论的选项的摘要。

1。改变继承顺序

1
2
class Z(Y, X):
    ...

这将确保在使用super方法(包括Print方法)时,Y的方法被调用在X的方法之上。

2。显式调用y的print方法

1
2
3
4
class Z(X, Y):
    ...
    def Print(self):
        Y.Print(self)

这将确保在使用super时x的方法被调用,除了一个调用,它将显式调用y的Print

三。(不使用)显式调用第二个父类的方法

1
2
3
4
class Z(X, Y):
    ...
    def Print(self):
        self.__class__.__bases__[1].Print()

这将确保在使用super时x的方法被调用,除了一个调用,它将显式调用第二个父类的Print(在本例中是y)。