是否可以使用转换

时间:2016-11-29 13:12:27

标签: python transitions

我有一个类似

的模型类
class MyModel(HierarchicalMachine):
    Machine.__init__(self, states=self.states, transitions=self.transitions,  
                                                    initial='EstablishingWsConnection')
...

工作正常。

现在我想从我的模型中创建一个HierarchicalGraphMachine,如

model = MyModel()
GraphMachine = mfact.get_predefined(graph=True, nested=True)  
grMachine =self.GraphMachine(                        
                    send_event=False, 
                    auto_transitions=False, 
                    title="BootNotificationStates",
                    show_conditions=True)  
hgm = HierarchicalGraphMachine(model, grMachine)

hgm.model.show_graph('mystate.png') 

结果 mystate.png

是否可以将我的模型实例重用于图纸?

THX,

val

2 个答案:

答案 0 :(得分:1)

GraphMachine不是mfact.get_predefined(graph=True, nested=True)会给你的。{1}}那将是mfact.get_predefined(graph=True)。您在这里致电GraphMachine的内容已经是HierarchicalGraphMachine

为了做到这一点,您可以在以下代码段中创建HierarchicalGraphMachine

from transitions import Machine
from transitions.extensions import MachineFactory

myStates = ['walking', 'running']
myTransitions = [ { 'trigger': 'accelerate', 'source': 'walking', 'dest': 'running' } ]

graphNestedMachineClass = MachineFactory.get_predefined(
    graph=True, nested=True)
hierarchicalGraphMachine = graphNestedMachineClass(
    states=myStates, transitions=myTransitions, initial='walking')

如果您想在Machine中嵌入任何类型的HierarchicalGraphMachine并使用模型,可以将以下代码添加到上述代码段中。

class MyModel(object):
    pass

myModel = MyModel()

moreStates = [
    'waiting',
    {'name': 'moving', 'children': hierarchicalGraphMachine }
]
moreTransitions = [
    { 'trigger': 'wait', 'source': '*', 'dest': 'waiting'},
    {'trigger': 'move', 'source': 'waiting', 'dest': 'moving_walking'}
]

parentHierarchicalGraphMachine = graphNestedMachineClass(
    model=myModel, states=moreStates, transitions=moreTransitions, initial='waiting')

现在你可以在各州之间转机:

print myModel.state  # prints 'waiting'
myModel.move()
print myModel.state  # prints 'move_walking'
myModel.accelerate()
print myModel.state  # prints 'move_running'
myModel.wait()
print myModel.state  # prints 'waiting'

你可以使用例如myModel.graph.draw('mystate.png', prog='dot')生成如下所示的状态图。

mystate.png

有关更多详细信息,请考虑查看位于转换存储库的factory.py路径中的转换transition/extension的源代码。还要看一下同一个存储库的顶层目录中非常好的README.md

过渡存储库可通过GitHub在https://github.com/tyarkoni/transitions获得。

答案 1 :(得分:1)

正如this回答已经说明的那样,建议的解决方案是将HierarchicalStateMachine嵌套到HierarchicalGraphMachine。现在transitions包含bug,它会影响解析嵌套状态的方式。这就是为什么它看起来有点奇怪。这将很快修复!最终,这个:

解决方案1:嵌套

from transitions.extensions import MachineFactory as factory

HSM = factory.get_predefined(nested=True)
GraphHSM = factory.get_predefined(nested=True, graph=True)

class MyModel(HSM):
    def __init__(self):
        self.states = ['A', 'B', 'C']
        self.transitions = [['go', 'A', 'B'],
                            ['go', 'B', 'C'],
                            ['go', 'C', 'A']]
        super(MyModel, self).__init__(self, states=self.states,       
                                      transitions=self.transitions,
                                      auto_transitions=False, initial='A')

mymodel = MyModel()

# define the nesting for the new machine
states = [{'name': 'mymodel', 'children': mymodel}]
# set the initial state to A of mymodel. Replace the underscore
# with the seperatore you are using
graph_machine = GraphHSM(states=states, auto_transitions=False,
                         title="Reused Machine", initial="mymodel_A")
graph_machine.graph.draw('reuse.png', prog='dot')

应该导致: enter image description here

同样,这是推荐的方式。但是,如果你真的需要让你的状态处于新创建的机器的根级别,那么你可以修改两台机器的内部和猴子补丁你的方式去荣耀。 transitions在两个集合中管理其中心部分:包含states的列表和包含events的字典(包含状态转换)。第二件事要知道,转换会在图表有效时更新图表。 NestedTransition类型的对象不知道如何做到这一点。所以这就是你能做的:

解决方案2:修补

# Create a new graph_machine which is initialized in mymodel's  state
graph_machine = GraphHSM(mymodel, title="Patched Machine",
                         states=[mymodel.state],
                         initial=mymodel.state)
# shallow copy the core parts to the new machine
graph_machine.events = mymodel.events
graph_machine.states = mymodel.states
# reinitialize the graph with the new configuration
mymodel.get_graph(force_new=True)

# 'upcast' the transitions to be of the type NestedGraphTransition
from transitions.extensions.factory import NestedGraphTransition
for event in mymodel.events.values():
    event.machine = graph_machine
    for lists in event.transitions.values():
        for transition in lists:
            transition.__class__ = NestedGraphTransition
# use the machine and test if the graph has been updated
mymodel.go()
mymodel.graph.draw('patching.png', prog='dot')

结果你会得到这个: enter image description here

我不知道第二个解决方案是如何防弹的,但我想把它留在这里作为{em>扩展文档,了解transitions如何操作...当然我是好奇,如果它确实有效; P。