python - 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}")
我想添加一个状态,任何触发器都保持相同状态,不调用转换,不明确指定每个可能的触发器,也不忽略所有无效触发器(因为这非常适合调试)。
例如,我想要一个crystal
可以通过触发crystalize
from达到的状态liquid
,对此任何事件都不会执行任何操作。
这可以通过图书馆实现吗?
表达这个问题的另一种方式是ignore_invalid_triggers=True
只针对特定州,而不是所有州。
解决方案
与转换类似,状态也可以用字典定义:
from transitions import Machine, MachineError
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'},
# add a transition to 'crystal' which is valid from anywhere
{'trigger': 'crystallize', 'source': '*', 'dest': 'crystal'},
]
self.machine = Machine(
model=self,
states=['solid', 'liquid', 'gas',
# initialized 'crystal' with dictionary
{'name': 'crystal', 'ignore_invalid_triggers': True}],
transitions=transitions,
initial='solid',
send_event=True
)
m = Matter()
assert m.is_solid()
try:
m.cool() # raises a machine error since cool cannot be called from 'solid'
assert False
except MachineError:
pass
assert m.crystallize() # transitions to 'crystal'
assert m.is_crystal()
assert not m.heat() # note that the transition will return 'False' since it did not happen but no exception was thrown
assert m.is_crystal() # state machine is still in state 'crystal'
代替{'name': 'crystal', 'ignore_invalid_triggers': True}
你也可以通过State(name='crystal', ignore_invalid_triggers=True)
。此表格在文档的状态部分中提到:
但在某些情况下,您可能希望默默地忽略无效触发器。您可以通过设置 ignore_invalid_triggers=True 来做到这一点(在逐个州的基础上,或对所有州全局):
推荐阅读
- ansible - 如何获取所有节点列表 IP 地址?
- python - 在 python pandas 中访问 csv 文件的 dict 列
- python - 从列表中删除元素并在同一语句中打印新列表
- html - MutationObserver:如何观察 flex child 的宽度/高度的变化?
- ruby-on-rails - 使用从属/辅助控制器上传图片
- c# - ASP.NET MVC C# - 将数据从控制器传递到类
- time-series - “如何同时编码多个月度时间序列的季节性分解”
- android - 嵌套片段如何从内部片段调用外部片段(作为父子关系)
- python - 如何将字典解压成结构化的DataFrame
- javascript - 在多次通过 Ajax 调用加载我的部分视图后,我的 Kendo 窗口失去了 closable:true