强制特定的__init __在Python中使用多个继承执行



我正在尝试正确获取__init__执行的顺序。层次结构由两个分支组成。左分支实现了右分支的一些抽象方法。在右分支中,也有一个拆分。现在,我希望他们执行:左上到底部,然后向下右上到底。

有没有办法在Python 3中实现这一目标?

因此,基本上以下应按顺序打印数字(没有):

from abc import abstractmethod, ABCMeta
class L1:
    def __init__(self):
        super().__init__()
        print(1)
class R1(metaclass=ABCMeta):
    def __init__(self):
        super().__init__()
        print(3)
    @abstractmethod
    def m(self):
        pass
class L2(L1):
    def __init__(self):
        super().__init__()
        print(2)
    def m(self):
        pass
class R2a(R1):
    def __init__(self):
        super().__init__()
        print(4)
class R2b(R1):
    def __init__(self):
        super().__init__()
        print(4)
class X(L2, R2a):
    pass
class Y(L2, R2b):
    pass
x = X()
print("--")
y = Y()

不幸的是,我无法更改L2和R2的顺序,因为L2实现了R2的抽象方法(如果我更改该方法,则会出现错误)。

可能吗?

(您知道考虑MRO解决此类问题的好方法吗?)

编辑:我以为我没关系,但是我想注意到,在我的真实结构中,实际上在L侧有一颗钻石,例如L2A(L1),L2B(L1)(L1)和L2(L1A,L2A)。那是完全分开一些功能。

怎么样:

from abc import abstractmethod, ABCMeta
class L1:
    def __init__(self):
        self.init()
        super().__init__()
    def init(self):
        print(1)
class R1(metaclass=ABCMeta):
    def __init__(self):
        print(3)
        super().__init__()
    @abstractmethod
    def m(self):
        pass
class L2(L1):
    def __init__(self):
        super().__init__()
    def init(self):
        super().init()
        print(2)
    def m(self):
        pass
class R2a(R1):
    def __init__(self):
        super().__init__()
        print(4)

class R2b(R1):
    def __init__(self):
        super().__init__()
        print(4)
class X(L2, R2a):
    pass
class Y(L2, R2b):
    pass
x = X()
print([cls.__name__ for cls in X.mro()])

产生

1
2
3
4
['X', 'L2', 'L1', 'R2a', 'R1', 'object']

我认为您不能更改MRO,['X', 'L2', 'L1', 'R2a', 'R1', 'object']。但是您可以选择在super().__init__()之前或之后放置初始化语句。

将打印语句放在super().__init__()之前,以MRO的顺序为您提供打印语句。之后将它们放置,倒转订单。

您希望订单部分逆转:l2之前的L1,R2之前的R1。

当我们到达L1时,通过调用self.init(),我们可以在MRO链的开头开始,并以所需的顺序致电initL1, L2

我更喜欢避免使用超级:

class A:
    def __init__(self):
        print('init A')
class B:
    def __init__(self):
        print('init B')
class C(B,A):
    def __init__(self):
        A.__init__(self)
        B.__init__(self)
        print('init C')
c = C()

此打印:

init A
init B
init C

因此,对于您的具体情况,只需致电_ init _ in无论您想要什么顺序。真的。去尝试一下。钻石或没有钻石,它可以很好地工作。

eg:

class X(L2,R2a):
    def __init__(self):
        L1.__init__(self)
        L2.__init__(self)
        R1.__init__(self)
        R2a.__init__(self)

如果您需要调用 init 以供层次结构中的更高的内容,并且您害怕对某些班级的 init 重复函数对某些对象进行重复函数。

例如:

class L1:
    def __init__(self):
        try:
            if self.l1_initialised:
                return
        except NameError:
            self.l1_initialised = True
        blah blah blah

相关内容

  • 没有找到相关文章

最新更新