Pytransitions队列式分层状态机最终回退到init状态问题咨询
pytransitions HierarchicalMachine嵌套状态回退问题原因
核心问题原因
- 嵌套状态机用法不符合规范:pytransitions的HierarchicalMachine不支持将已独立实例化的状态机对象直接作为父状态的
children参数使用。你传入已实例化的PrepareMachine对象时,父状态机只会提取它的状态、回调、转换的配置定义,不会将这个独立实例和父状态机的子状态做绑定,二者是完全独立的两个状态机实例。 - 回调操作的对象错误:你在
PrepareMachine的状态回调中调用的self.to_connecting()、self.to_waiting(),实际操作的是提前初始化的那个独立PrepareMachine实例的状态,完全不会影响父状态机ProductionMachine内部的prepare子状态值。 - 父状态机的子状态未被操作:父状态机进入
prepare状态后,会默认将其子状态初始化为你定义的init,后续没有任何代码修改父状态机自身的子状态值,因此最终输出的状态就是prepare_init。你在日志中看到的一系列状态转换,都是那个独立PrepareMachine实例的运行日志,和父状态机无关。
正确实现方案
如果要实现嵌套子状态机的逻辑,不需要提前实例化子状态机,直接将子状态的配置写到父状态的children字段中即可,调整后的代码示例:
from transitions.extensions.factory import HierarchicalMachine import logging as log QUEUED = True class ProductionMachine(HierarchicalMachine): def __init__(self): states = [ "init", { "name": "prepare", "children": [ {"name": "init", "on_enter": self.entry_init}, {"name": "connecting", "on_enter": self.entry_connecting}, {"name": "waiting", "on_enter": self.entry_waiting}, ], "initial": "init" } ] super().__init__(states=states, initial="init", queued=QUEUED) self.add_transition("start_testing", "init", "prepare") def entry_init(self): print("common entry point ...") self.to_prepare_connecting() def entry_connecting(self): print("connecting multiple instruments ...") self.to_prepare_waiting() def entry_waiting(self): print("wait for response ...") log.basicConfig(level=log.INFO) machine = ProductionMachine() machine.start_testing() print(machine.state)
注意:嵌套子状态的自动生成的
to_方法名会带上父状态名前缀,因此从prepare_init转到prepare_connecting需要调用to_prepare_connecting而不是to_connecting。
内容的提问来源于stack exchange,提问作者Jan Krejci
相关产品推荐
相关产品推荐

