What about:
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()])
what gives
1 2 3 4 ['X', 'L2', 'L1', 'R2a', 'R1', 'object']
I do not think you can change the MRO, ['X', 'L2', 'L1', 'R2a', 'R1', 'object'] . But you can choose to place initialization instructions before or after super().__init__() .
Placing print statements before super().__init__() gives you print instructions in MRO order. Placing them subsequently cancels the order.
You want the order to be partially canceled: L1 to L2, R1 to R2a.
When we reach L1 by calling self.init() , we will start first at the beginning of the MRO chain and call init in the desired order: L1, L2 .
source share