首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跃迁嵌套

跃迁嵌套
EN

Stack Overflow用户
提问于 2019-01-22 19:22:20
回答 1查看 864关注 0票数 1

因此,我一直在查看github上的封闭性问题,并在googling上搜索以解决这个问题。但我一直没能解决我的问题,这似乎是正确的地方。我已经在github上打开了一个问题,但我不确定这样做是否正确。我正在制作一个状态机,它可以包含几个子状态,这些子状态也都是状态机。根据自述文件的说法,这基本上可以归结为重用高速加工。

我的最高级别SM如下所示:

代码语言:javascript
复制
from transitions.extensions import LockedHierarchicalMachine as Machine
from coordination.running import RunningStateMachine

logging.basicConfig(level=logging.ERROR)
logging.getLogger("transitions").setLevel(logging.INFO)

class RPPStateMachine(Machine):
    def __init__(self, name):
        self._running = RunningStateMachine()
        self.name = name
        states = [
            "init",
            {"name": "running", "children": self._running},
            "stop",
        ]

        Machine.__init__(self, states=states, initial="init")

        self.add_transition("e_run", "init", "run", after=self.run_machine)
        self.add_transition("e_stop", "*", "stop")

    def run_machine(self):
        self._running.initialize()

正如您所看到的,状态机有三个状态:initrunningstop。一旦事件e_run()通过类似的方式发送

代码语言:javascript
复制
machine = RPPStateMachine("my_machine")
machine.e_run()

机器转换到running状态。

我以一种间接的方式去做,因为我希望事情自动发生。e_run()会导致转换到running,然后run_machine调用运行类的initialize方法,该方法会触发一个事件来启动事件链。下面我展示给running看,这就清楚了。

因此,运行状态定义为

代码语言:javascript
复制
from transitions.extensions import LockedHierarchicalMachine as Machine
from coordination.test_mode import TestingStateMachine
from coordination.release_mode import ReleaseStateMachine

class RunningStateMachine(Machine):
    def __init__(self):
        self._test_mode = TestingStateMachine()
        self._release_demo = ReleaseStateMachine()
        states = [
            "init",
            "configuration",
            "idle",
            {"name": "test_mode", "children": self._test_mode},
            {"name": "release_mode", "children": self._release_mode},
        ]

        Machine.__init__(self, states=states, initial="init")
        self.add_transition("e_start_running", "init", "configuration", after=self.configuration)
        self.add_transition("e_success_config", "configuration", "idle")
        self.add_transition("e_test_mode", "idle", "test_mode")
        self.add_transition("e_release_mode", "idle", "release_mode")
        self.add_transition("e_start_running", "idle", "init")

    def initialize(self):
        print("Initialization step for running, emitting e_start.")
        self.e_start_running()

    def configuration(self):
        print("Configuring...")
        print( "Current state: " + self.state)

        self.e_success_config()

它类似于它的父级,由几个州和几个子州组成。我还启用了日志记录,以查看输入和退出的状态。根据我的经验,嵌套状态机非常有用,因为您可以重用以前编写的状态。此外,随着您的状态机的增长,它有助于保持更模块化的东西。因此,没有一种状态会变得巨大,难以阅读/理解。

因此,不寻常的行为是,当e_run()被调用时,我得到了

代码语言:javascript
复制
INFO:transitions.core:Entered state running
INFO:transitions.core:Entered state running_init
Initialization step for running, emitting e_start.
INFO:transitions.core:Exited state init
INFO:transitions.core:Entered state configuration
Configuring...
current state: configuration
INFO:transitions.core:Exited state configuration
INFO:transitions.core:Entered state idle

如你所见

代码语言:javascript
复制
machine.state
>>> 'running_init'

代码语言:javascript
复制
machine._running.state
>>> 'idle'

当然,我可以将转换定义移到父状态,但这并不方便。我不能对所有的州都这么做。很明显,我希望每个子州都对自己的行为负责。这里的普遍做法是什么?这是一种错误还是有意的行为?

我如何将状态机整齐地嵌套在彼此之间?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-16 07:50:49

transitions 0.7.1开始,将一个状态机作为另一个状态机的子状态传递,将将传递的机器的所有状态复制到父机器。通过的状态机保持不变(正如我们讨论的这里)。

代码语言:javascript
复制
from transitions.extensions import MachineFactory

HSM = MachineFactory.get_predefined(nested=True)

fsm = HSM(states=['A', 'B'], initial='A')
hsm = HSM(states=['1', {'name': '2', 'children': fsm}])

# states object have been copied instead of referenced, they are not identical
assert fsm.states['A'] is not hsm.states['2_A']
hsm.to_2_A()

# both machines work with different models
assert fsm.models[0] is not hsm.models[0]
assert fsm.state is not hsm.state

当前推荐的工作流是将模型和机器拆分,并仅将机器视为其父级的某种“蓝图”:

代码语言:javascript
复制
from transitions.extensions import MachineFactory


class Model:
    pass


HSM = MachineFactory.get_predefined(nested=True)

# creating fsm as a blueprint, it does not need a model
fsm = HSM(model=None, states=['A', 'B'], initial='A')
# use a model AND also
model = Model()
hsm = HSM(model=['self', model], states=['1', {'name': '2', 'children': fsm}])

# will only update the machine's state
hsm.to_1()
assert model.state != hsm.state
# will update ALL model states
hsm.dispatch("to_2_B")
assert model.state == hsm.state

但是,这并不能取代将机器正确隔离(和/或限定作用域)嵌套到父计算机中。已经创建了一个特性草案,并有望在可预见的将来实现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54315078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档