如果转换条件失败,如何自动重新运行状态?

时间:2017-11-24 14:23:25

标签: python transition fsm

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

初始状态正在寻找GUI窗口。找到窗口后,状态机将切换到下一个状态。

enter image description here

请考虑以下代码:

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

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

2 个答案:

答案 0 :(得分:0)

由于您只需要从一种状态转换到另一种状态,因此您可以在检查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()

答案 1 :(得分:0)

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