Pytransitions 中的状态历史

State history in Pytransitions

我正在使用 Pytransitions 并且我有一些状态机,例如

from transitions import Machine
from transitions import EventData


class Matter(object):
    def __init__(self):
        transitions = [
            {'trigger': 'heat', 'source': 'solid', 'dest': 'liquid'},
            {'trigger': 'heat', 'source': 'liquid', 'dest': 'gas'},
            {'trigger': 'cool', 'source': 'gas', 'dest': 'liquid'},
            {'trigger': 'cool', 'source': 'liquid', 'dest': 'solid'}
        ]
        self.machine = Machine(
                model=self,
                states=['solid', 'liquid', 'gas'],
                transitions=transitions,
                initial='solid',
                send_event=True
        )

    def on_enter_gas(self, event: EventData):
        print(f"entering gas from {event.transition.source}")

    def on_enter_liquid(self, event: EventData):
        print(f"entering liquid from {event.transition.source}")

    def on_enter_solid(self, event: EventData):
        print(f"entering solid from {event.transition.source}")

是否有一些图书馆支持的方式来跟踪各州的所有历史?

我现在手动做的是在init上:

after_state_change=lambda event: self._on_after_state_change(event)

def _on_after_state_change(self, event: EventData):
    to_state = event.transition.dest
    self._history_df.append({
        "start_index": self._index,
        "state": to_state
    }, ignore_index=True)

我想知道该库是否支持某些 可查询 日志记录,这意味着不仅可以将事件转储到文件中,还可以将它们保存在列表中。

Transitions 没有内置历史记录。如果您只想跟踪以前的状态,this GitHub 问题可能会有所帮助:

Since the stateful object with transitions is the model you can use the state property to track state changes:

from transitions import Machine
import collections


# if you like your machine to act as a model, let Model inherit from Machine
class Model(object):

    def __init__(self, history_length):
        self.state_history = collections.deque(maxlen=history_length)

    @property
    def state(self):
        return self.state_history[-1]

    @state.setter
    def state(self, value):
        self.state_history.append(value)


model = Model(3)
machine = Machine(model, states=['A', 'B', 'C', 'D'], initial='A')
print(model.state)  # >>> A

model.to_B()
model.to_C()
model.to_A()
model.to_D()

print("->".join(model.state_history))  # >>> C->A->D

这仅适用于 model_attribute='state'(默认值)。如果您更改了 'stateful' 模型字段的名称,则需要相应地调整上述属性。

如果您对所有 EventData 感兴趣,您的方法似乎就是解决方案。你可以省略 lambda。 after_state_change=self._on_after_state_changeafter_state_change='_on_after_state_change'(如果方法是模型的一部分)应该足够了。

上面提到的 dequeue(或 queue.Queue)在某种程度上是 'queryable',您可以对其使用过滤器或列表理解。如果您需要更复杂的东西,pandas (which you probably already use considering your history name) or sqlite 可能更合适。