带有模块`pysm`的Python有限状态机

时间:2018-01-08 17:05:07

标签: python state-machine

为什么这段代码显然不能正常工作?

下面的机器有两种状态:idletravelling,以及两个名为go的转换。我使用register_handlers附加到此转换on_enteron_go处理程序。我希望这段代码的结果是两个打印,每个处理程序之一。出于某种原因,似乎只有on_enter处理程序被执行。

import pysm

machine = pysm.pysm.StateMachine('ship')

idle = pysm.pysm.State('idle')

class TravellingState(pysm.pysm.State):
    def on_go(self, state, event):
        print("on_go function called")

    def on_enter(self, state, event):
        print("on_enter function called")

    def register_handlers(self):
        self.handlers = {
            'enter': self.on_enter,
            'go': self.on_go, # doesnt work?
        }

travelling = TravellingState('travelling')

machine.add_state(idle, initial=True)
machine.add_state(travelling)

machine.add_transition(from_state=idle, to_state=travelling, events=['go'])

machine.initialize()

machine.dispatch(pysm.pysm.Event('go', cargo={'target':(1,1)}))

1 个答案:

答案 0 :(得分:0)

gotravelling州将处理的事件。 但是你最初处于idle状态。它会忽略go事件。

您已在idle事件中创建了从travellinggo的转换。因此,您基本上看到的是从idletravelling的转换,因此调用enter实例中的Travelling处理程序。

如果要在go状态下处理idle,请在idle实例中指定处理程序:

def on_go(state, event):
    print('on_go from idle')

idle = pysm.pysm.State('idle')
idle.handlers = {'go': on_go}

然后致电

machine.dispatch(pysm.pysm.Event('go', cargo={'target':(1,1)}))

调用on_go状态的idle处理程序。

同时

保留您的代码,如果您再次调用go事件(已处于travelling状态),则会调用您的处理程序。

machine.dispatch(pysm.pysm.Event('go', cargo={'target':(1,1)}))

完整的工作示例:

import pysm

machine = pysm.pysm.StateMachine('ship')

def on_go(state, event):
    print('on_go from idle')

idle = pysm.pysm.State('idle')
idle.handlers = {'go': on_go}


class TravellingState(pysm.pysm.State):
    def on_go(self, state, event):
        print("on_go from travelling")

    def on_enter(self, state, event):
        print("on_enter from travelling")

    def register_handlers(self):
        self.handlers = {
            'enter': self.on_enter,
            'go': self.on_go,
        }

travelling = TravellingState('travelling')

machine.add_state(idle, initial=True)
machine.add_state(travelling)

machine.add_transition(from_state=idle, to_state=travelling, events=['go'])

machine.initialize()

machine.dispatch(pysm.pysm.Event('go', cargo={'target':(1,1)}))
machine.dispatch(pysm.pysm.Event('go', cargo={'target':(1,1)}))

正如预期的那样输出:

# go event is dispatched
on_go from idle
# Now the transition happens
on_enter from travelling
# go is dispatched again
on_go from travelling