如何以更清晰的方式重写状态机?

2024-03-29 06:31:02 发布

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

我正在与外部设备交互,我必须按顺序发出某些命令。有时我不得不向后跳,重做步骤。伪代码(实际代码有更多的步骤和跳转):

enter_update_mode()  # step 1
success = start_update()
if not success:
    retry from step 1
leave_update_mode()

我如何以最干净的方式处理这个问题?我现在做的是定义一个枚举,并编写一个状态机。这是可行的,但很难看:

class Step(Enum):
    ENTER_UPDATE_MODE = 1
    START_UPDATE = 2
    LEAVE_UPDATE_MODE = 3
    EXIT = 4

def main():
    next_step = Step.ENTER_UPDATE_MODE

    while True:
        if next_step == Step.ENTER_UPDATE_MODE:
            enter_update_mode()
            next_step = Step.START_UPDATE
        elif next_step == Step.START_UPDATE:
            success = start_update()
            if success:
                next_step = Step.LEAVE_UPDATE_MODE
            else:
                next_step = Step.ENTER_UPDATE_MODE
        ....

我可以想象另一种方法是只调用嵌套的函数。只要这只是几个层次的深度,就不应该是问题:

def enter_update_mode():
    # do stuff ...
    # call next step:
    perform_update()

def perform_update():
    # ...
    # call next step:
    if success:
        leave_update_mode()
    else:
        enter_update_mode()

我已经研究了python-statemachine模块,但它似乎是用来建模状态机的。您可以定义状态并查询它所处的状态,还可以将行为附加到状态。但这不是我想要的。我正在寻找一种方法,以一种非常简单、命令式的方式编写行为代码,就像您用于伪代码或人类指令一样

还有一个模块可以将goto添加到Python中,但我认为这是一个笑话,不想在生产中使用它:-)

注:

  • 此代码是同步的,这意味着它是一个终端应用程序或一个单独的线程。与其他代码同时运行会增加复杂性。如果解决方案允许(例如,通过使用yield),这将是一种奖励,但不是必需的
  • 我遗漏了很多重试逻辑。一个步骤只能重试一定次数
  • 显式状态机与命令式风格的相关讨论:https://softwareengineering.stackexchange.com/q/147182/62069