【问题标题】:How to automatically re-run a state if transition condition fails?如果转换条件失败,如何自动重新运行状态?
【发布时间】:2018-05-08 14:00:55
【问题描述】:

我正在用python编写屏幕抓取应用程序,使用transitions来处理状态机。

初始状态是寻找一个 GUI 窗口。找到窗口后,状态机更改为下一个状态。

请考虑以下代码:

class ScreenScrapper(object):
    window = None

    def is_window_found(self):
        return bool(self.window)

    def state_look_for_window(self):
        window = get_window()  # Returns a bitmap object or None if window is not found
        self.do_work()

    def state_do_work(self):
        print('Do some work!')
        print('Window er: ', self.window)


states = ['dummy', 'state_look_for_window', 'state_do_work']

transitions = [
    {'trigger': 'start', 'source': 'dummy', 'dest': 'state_look_for_window', 'after': 'state_look_for_window'},
    {'trigger': 'do_work', 'source': 'state_look_for_window', 'dest': 'state_do_work', 'conditions': 'is_window_found', 'after': 'state_do_work'},
]

screen_scrapper = ScreenScrapper()
Machine(model=screen_scrapper, states=states, transitions=transitions, initial='dummy')

screen_scrapper.start()

在这个简单的示例中,start 将状态从 dummy 更改为 state_look_for_windowafter 回调将查找窗口,然后将状态更改为 state_do_work。这个转换的条件是is_window_found

问题:只要转移条件is_window_found返回False,如何再次执行state_look_for_window?请注意:我只对可以包含在状态机中的解决方案感兴趣。也就是说,外面的唯一代码必须是screen_scrapper.start()

【问题讨论】:

  • 不应该while not is_window_found 工作吗?
  • 我已经考虑过那个解决方案,它会奏效。但是过渡库非常积极地使用条件,所以我怀疑一定有更好更正确的方法来做到这一点,尤其是因为这种用例非常普遍。

标签: python transition fsm


【解决方案1】:

由于您只需要从一种状态转换到另一种状态,因此您可以在检查 is_window_found 后进行状态转换

我觉得应该是这样的

    def state_look_for_window(self):
    if not is_window_found:
        self.state_look_for_window() 
    else:
        window = get_window()  # Returns a bitmap object or None if window is not found
        self.do_work()

【讨论】:

  • 这正是我的第一个方法。但它返回以下错误:RuntimeError: maximum recursion depth exceeded
  • 我不确定这个状态是如何工作的。可能会添加另一个从您的状态转换到相同状态的触发器。然后调用触发器而不是方法本身。因为python的标准递归深度不是很深。
【解决方案2】:

我认为您是在要求“自反转换”,这是一个与源和目标具有相同状态的触发器。 我会用另一个名为“Window Ready”的状态替换您当前的图表,并为该状态指定一个内部转换,您在该状态下保持循环,直到找到所需的 Window GUI。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多