在Fysom初始化之前从类内部调用状态回调函数

时间:2017-12-07 15:45:27

标签: python

我正在使用Fysom在Python中创建一个有限状态机,我看到一个我不知道为什么会发生的问题。

我创建了一个MyClass类,在该类中我创建了一个self.fsm成员,该成员是Fysom的一个实例。

出于某种原因,当达到有限状态机的第一个状态时,我的类的fsm成员似乎不存在。但是当达到第二个状态时,确实存在。

from fysom import Fysom

class MyClass(object):
    def __init__(self):
        self.fsm = Fysom({
            'initial': 'start',
            'events': [ { 'src': 'start', 'name': 'go', 'dst': 'end' } ],
            'callbacks': {
                # States callbacks
                'onstart': self.on_start_callback,
                'onend': self.on_end_callback,
                # Events callbacks
                'onbeforego': self.show_event
            }
        })

    def on_start_callback(self, event):
        print "state: start"
        print "self attrs: {}".format(self.__dict__)

    def on_end_callback(self, event):
        print "state: end"
        print "self attrs: {}".format(self.__dict__)

    def show_event(_, event):
        print "event: {}".format(event.event)

def main():
    instance = MyClass()
    instance.fsm.go()

if __name__ == "__main__":
    main()

这是输出:

state: start
self attrs: {}
event: go
state: end
self attrs: {'fsm': <fysom.Fysom object at 0x7fe948f11510>}

为什么在达到初始状态(fsm)时,MyClass的{​​{1}}成员不存在?是不是应该在类构造函数start中创建和初始化?

我的猜测是__init__(这是有限状态机的初始状态的回调)在创建on_start_callback实例时以及在它被分配给{{1成员,因此在尝试访问Fysom时失败。 实际发生了什么,是正确的行为吗?

我通过创建一个什么也不做的初始状态(或者至少它根本不访问fsm)找到了该问题的解决方法,然后从self.fsm函数我手动触发转换到访问self的实际初始状态的事件(此时已定义)。

1 个答案:

答案 0 :(得分:1)

你猜是正确的,这是正确的行为。 __init__按顺序执行。您的回调是在创建fsm时以及在将其分配给self.fsm之前发生的,因此self.__dict__仍为空。

在您成功实例化并分配了fsm之后,您可以在__init__内对其进行初始化:

class MyClass(object):
    def __init__(self):
        self.fsm = Fysom({
            'initial': 'none',
            'events': [
                { 'name': 'initialize', 'src': 'none', 'dst': 'start'},
                { 'src': 'start', 'name': 'go', 'dst': 'end' } ],
            'callbacks': {
                # States callbacks
                'onstart': self.on_start_callback,
                'onend': self.on_end_callback,
                # Events callbacks
                'onbeforego': self.show_event
            }
        })
        self.fsm.initialize()