Как уже было сказано 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')
Если в результате этого:
Опять же, это рекомендуемый способ.Однако, если у вас действительно должны иметь свои состояния на уровне корня только что созданной машины, вы можете возиться с внутренними частями обеих машин, а обезьяна заплатит вам путь к славе. 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')
В результате вы получите это:
Я не знаю, как пуленепробиваемые второе решение но я хотел оставить его здесь как немного документация о том, как работает transitions
... и, конечно, мне было любопытно, если он действительно работает;