繁体   English   中英

Python多继承中的动态super()

[英]Dynamic super() in multi-inheritance in Python

我有这样的代码:

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

它搜索Print根据

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

并在X首次找到它。 但是,如果我想z.Print()运行Y.Print() ,则可以使用一个明确的类名,例如:

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

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

我真的取决于您要做什么。 如果要确保同时X.PrintY.Print ,则需要在X.PrintY.Print中都添加超级调用,并使用占位符Print方法添加基类。

如果要根据某些条件调用X.PrintY.Print ,则继承可能对您来说是错误的模型。 您可能希望尝试使用合成。 在这里,您可以编写一个继承自XY ,但将它们的实例作为成员并知道如何使用它们。 例如。

遗产

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()

输出:

Inheiritance
X
Y

组成

class Composition:
    def __init__(self):
        self.x = X()
        self.y = Y()
    def Print(self):
        print("Composition")
        self.x.Print()
        self.y.Print()

Composition().Print()

输出:

Composition
X
Y

为了将来参考,以下是注释中讨论的选项的摘要。

1.更改继承顺序

class Z(Y, X):
    ...

这样可以确保在使用super (包括Print方法)在X方法上调用Y方法。

2.显式调用Y的Print方法

class Z(X, Y):
    ...
    def Print(self):
        Y.Print(self)

这将确保在使用super时,X的方法要比Y的方法被调用,但那一次调用除外,后者将显式调用Y的Print

3.(不要使用)显式调用第二个父类的方法

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

这将确保在使用super时,X的方法要比Y的方法被调用,但一次调用除外,后者将显式调用第二个父类的Print (在本例中为Y)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM