当前位置 博文首页 > python状态机transitions库详解

    python状态机transitions库详解

    作者:sandalphon4869 时间:2021-08-11 18:37

    目录
    • 一、简介
    • 二、逐步创建
    • 三、直接初始化创建
    • 四、运行
    • 附录

    一、简介

     transitions库

    pip install transitions

    状态机

    state:状态节点

    transition:用于从一个状态节点移动到另一个状态节点

    教程

    https://pypi.org/project/transitions/

    二、逐步创建

    创建对象

    创建一个继承object的类Number的实体对象number,然后调用transitions.Machine()将状态机绑定到这个实体对象上。

    from transitions import Machine
    
    class Number(object):
        pass
        
    number = Number()
    machine = Machine(model=number)

    然后我们得到了两个东西,一个是状态机machine,一个是具体的实体对象number,。
    之后设定状态机是用machine,运行状态机是用具体的实体对象number

    添加state

    state可以指定:

    • name:状态节点的名字,必须指定。
    • on_enter:进入该状态节点会产生的事件(注意,初始节点不会调用,因为已经进入了。见【验证代码】)
    • on_exit:退出该状态节点会产生的事件
    '''
    构造简单的state
    '''
    # 只指定名字
    zero = '0'
    
    # 通过State()
    from transitions import State
    one = State('1')
    
    # 构造字典
    two = {'name':'2'}
    '''
    构造复杂的State
    '''
    class Number(object):
        def hello(self):
            print('hello')
        pass
    
    zero = '0'
    
    
    from transitions import State
    one = State('1', on_enter=['hello'], on_exit=['hello'])
    
    
    two = {'name':'2', 'on_enter':['hello'], 'on_exit':['hello']}
    
    '''
    添加state
    '''
    # 逐个
    machine.add_states(zero)
    
    # 一起添加
    machine.add_states([one, two])

    添加transition

    transition需要指定三个东西:

    • trigger:表示transition的名字(注意,不能和Number类中方法重名了)
    • source:原状态节点
    • dest:目标转态节点
    machine.add_transition('zero_to_one', source='0', dest='1')    # 有效
    machine.add_transition('zero_to_one', source='1', dest='2')    # 无效

    注意,只有第一个匹配zero_to_one的transition有效。因此,上面最后一行中定义的转换不会做任何事情。

    三、直接初始化创建

    states = [
        {'name':'0'},
        {'name':'1'},
        {'name':'2', 'on_enter':['hello'], 'on_exit':['hello']},
    ]
    # way1
    transitions = [
        { 'trigger': 'zero_to_one', 'source': '0', 'dest': '1' },
        { 'trigger': 'zero_to_two', 'source': '0', 'dest': '2' },
        { 'trigger': 'one_to_two', 'source': '1', 'dest': '2' },
        { 'trigger': 'any_to_zero', 'source': '*', 'dest': '0' },   # 任意前状态 '*'
    ]
    
    # way2
    transitions = [
        ['zero_to_one', '0', '1' ],
        ['one_to_two', '1', '2' ],
        ['any_to_zero', '*', '0' ],    # 任意前状态 '*'
    ]
    
    from transitions import Machine
    
    class Number(object):
        def hello(self):
            print('hello')
        pass
        
    number = Number()
    machine = Machine(
    	model=number, 
    	states=states, 
    	initial=states[0]['name'],
    	transitions=transitions
    )
    

    四、运行

    输出当前状态

    now_state = number.state
    print(now_state)

    判断当前状态

    格式:is_«state name»()。返回True False。

    number.is_0()

    强行移动状态

    格式:to_«state name»()。返回True;如果移动到不存在的状态节点从而失败,那么抛出AttributeError

    number.to_2()

    获取到某个状态的transition

    machine.get_triggers('0')
    # ['to_0', 'to_1', 'to_2', 'zero_to_one', 'any_to_zero']

    调用transition

    # way 1
    number.zero_to_one()
    
    # way 2
    number.trigger('zero_to_one')

    附录

    什么叫做初始状态已经进入

    from transitions import Machine
    
    class Number(object):
        def hello(self):
            print('hello')
        pass
    number = Number()
    
    states = [
        {'name':'0', 'on_enter':['hello']},
        {'name':'1'},
        {'name':'2'},
    ]
    transitions = [
        { 'trigger': 'zero_to_one', 'source': '0', 'dest': '1' },
        { 'trigger': 'zero_to_two', 'source': '0', 'dest': '2' },
        { 'trigger': 'one_to_two', 'source': '1', 'dest': '2' },
        { 'trigger': 'any_to_zero', 'source': '*', 'dest': '0' },   # 任意前状态 '*'
    ]
    Machine(model=number, states=states, initial=states[0]['name'],transitions=transitions)
    
    init_state = number.state
    print(init_state)				
    
    number.zero_to_one()
    print(number.state)
    
    number.any_to_zero()			
    print(number.state)
    '''
    0		# 第一次不会调用,因为已经进入了
    1
    hello	# 再进来时才调用
    0
    '''
    
    jsjbwy
    下一篇:没有了