如何通过多重继承确保方法调用的特定顺序?

2024-10-01 00:14:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个包含如下类的包:

# pseudo-code
class Block:
    def start(self):
        if not initialized:
            initialze_from_default # fail-safe

class BlockPersistent(Block):
    def start(self):
        if not initialized:
            initialze_from_saved_state # does nothing if no state was saved
        super().start()

class BlockRemote(Block):
    def start(self):
        if not initialized:
            initialze_from_remote_server # does nothing if network I/O fails
        super().start()

应用程序可以使用这三个类中的任何一个作为自己类的基础。但是,当应用程序代码想要定义一个同时支持客户机/服务器通信和持久状态的块时,它必须注意正确的顺序:

class SomeBlock(BlockRemote, BlockPersistent):
    ...

因为在这种情况下,唯一有意义的初始化顺序是:

  1. 首先尝试从服务器获取最新的值
  2. 然后尝试一下,如果我们有一些保存的价值
  3. 使用默认值作为最后手段

我希望做到这一点:

class SomeBlock(BlockPersistent, BlockRemote): # wrong order!

也将以正确的顺序调用所有start函数(或者至少会失败,并显示关于错误顺序的明确错误消息)。对于我的问题,有什么推荐的方法吗


我希望能得到一些有用的反馈。如果不是,我可能会实现如下内容:

class Block:
    def _init_subclass(cls, ...)
        super()._init_subclass(...)
        # recursively visit all cls.__bases__,
        # collect all _start methods,
        # sort by PRIORITY (from highest to lowest)
        cls.starts = [...]

    def start(self):
        for func in self.starts:
            func(self)

    PRIORITY = 0
    def _start(self):
        if not initialized:
            initialze_from_default # fail-safe

class BlockPersistent(Block):
    PRIORITY = 10
    def _start(self):
        if not initialized:
            initialze_from_saved_state # does nothing if no state was saved

class BlockRemote(Block):
    PRIORITY = 20
    def _start(self):
        if not initialized:
            initialze_from_remote_server # does nothing if network I/O fails

Tags: fromselfifdefnotblockstartclass