python - 如何将参数传递给`transitions`库中的on_enter回调?
问题描述
我想使用transitions,并且需要一个我在文档中找不到的相当微不足道的功能,并且想知道它是否已实现:
我想on_enter
在某个状态上定义一个回调,但将一个参数传递给该回调。至少要知道我是从哪个州进入的。
从文档:
class Matter(object):
def say_hello(self): print("hello, new state!")
def say_goodbye(self): print("goodbye, old state!")
lump = Matter()
# Same states as above, but now we give StateA an exit callback
states = [
State(name='solid', on_exit=['say_goodbye']),
'liquid',
{ 'name': 'gas', 'on_exit': ['say_goodbye']}
]
machine = Machine(lump, states=states)
machine.add_transition('sublimate', 'solid', 'gas')
# Callbacks can also be added after initialization using
# the dynamically added on_enter_ and on_exit_ methods.
# Note that the initial call to add the callback is made
# on the Machine and not on the model.
machine.on_enter_gas('say_hello')
# Test out the callbacks...
machine.set_state('solid')
lump.sublimate()
>>> 'goodbye, old state!'
>>> 'hello, new state!'
我缺乏的是
def say_hello(self, param): print(f"hello, new state! here is your param: {param}")
这可以以某种方式很好地完成吗?
一个明显不好的解决方案是保留一个self._last_state
论点并自己坚持下去。
我正在寻找内置的东西。
解决方案
transitions
' 文档的部分称为传递数据:
...您可以将任何位置或关键字参数直接传递给触发器方法(在调用 add_transition() 时创建)[...] 您可以将任意数量的参数传递给触发器。这种方法有一个重要限制:状态转换触发的每个回调函数都必须能够处理所有参数。
对于您的特定示例,这可能如下所示:
from transitions import Machine
class Matter(object):
def say_hello(self, param):
print(f"hello, new state! Here is your param: {param}")
# Every callback MUST be able to process possible callback parameters
# If parameters are not needed, just use *args and **kwargs in the definition
def say_goodbye(self, *args):
print("goodbye, old state!")
lump = Matter()
machine = Machine(lump, states=[{'name': 'solid', 'on_exit': 'say_goodbye'},
'liquid',
{'name': 'gas', 'on_enter': 'say_hello'}],
transitions=[['sublimate', 'solid', 'gas']], initial='solid')
# pass param as arg
lump.sublimate(lump.state)
# or as kwarg
# lump.sublimate(param=lump.state)
还有第二种方法是通过传入构造函数来传递send_event=True
数据Machine
。这将改变transitions
将触发参数传递给回调的方式:
如果您在机器初始化时设置 send_event=True,则触发器的所有参数都将包装在 EventData 实例中并传递给每个回调。(EventData 对象还维护与事件关联的源状态、模型、转换、机器和触发器的内部引用,以防您需要访问这些以进行任何操作。)
这可能更适合您的用例,因为EventData
对象还包含有关已执行转换的信息,其中包含源状态的名称:
from transitions import Machine, EventData
class Matter(object):
def say_hello(self, event: EventData):
print(f"hello, new state! Here is your param: {event.kwargs['param']}. "
f"I came here from state '{event.transition.source}'.")
def say_goodbye(self, event):
print("goodbye, old state!")
lump = Matter()
machine = Machine(lump, states=[{'name': 'solid', 'on_exit': 'say_goodbye'},
'liquid',
{'name': 'gas', 'on_enter': 'say_hello'}],
transitions=[['sublimate', 'solid', 'gas']], initial='solid', send_event=True)
lump.sublimate(param=42)
推荐阅读
- c - 使用clock_gettime() 的正确方法是什么?
- laravel - yajra Datatables 过滤并排序不在数据库中的数据
- java - 如何在 2d Arraylist 上使用 TrimToSize 方法?
- xslt - 使用 xls 删除属性值等于 0 的 xml 节点
- mysql - Mysql LEFT JOIN 结合 INNER 和 Group By
- java - 如何使用 javax.xml.bind 将 XML 写入带有 xmlns 字段的 POJO?
- r - split-lapply- 组合一个大数据帧以避免内存问题?
- android - 如何在我的联系人列表中搜索和拨打电话?
- r - 闪亮的仪表板 tabitem 没有显示
- flask - Flask:无法解析包中的端点位置