问题描述
我想使用 transitions,并且需要一个我在docs,并想知道它是否已实施:
I want to use transitions, and need a rather trivial feature I could not find in the docs, and was wondering if it was implemented:
我想在某个状态上定义一个 on_enter
回调,但要向该回调传递一个参数.至少要知道我是从哪个州进入该州.
I want to define a on_enter
callback on some state, but pass a parameter to that callback. At least to know from which state I am entering the state.
来自文档:
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}")
这能以某种方式很好地完成吗?
Can this be done nicely somehow?
一个明显不好的解决方案是保留一个 self._last_state
参数并自己维护它.
我正在寻找内置的东西.
An obvious bad solution would be to keep a self._last_state
argument and maintain that myself.
I am looking for something built-in.
推荐答案
transitions
' 文档中名为 传递数据:
...您可以将任何位置或关键字参数直接传递给触发器方法(在调用 add_transition() 时创建)[...] 您可以将任意数量的参数传递给触发器.这种方法有一个重要的限制:状态转换触发的每个回调函数都必须能够处理所有参数.
对于您的特定示例,这可能如下所示:
For your particular example this could look like this:
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)
还有第二种传递数据的方法,即在 Machine
构造函数中传递 send_event=True
.这将改变 transitions
将触发参数传递给回调的方式:
There is also a second way to pass data by passing send_event=True
in the Machine
constructor. This will change the way how transitions
passes trigger parameters to callbacks:
如果您在机器初始化时设置 send_event=True,触发器的所有参数将被包装在一个 EventData 实例中并传递给每个回调.(EventData 对象还维护与事件关联的源状态、模型、转换、机器和触发器的内部引用,以防您需要访问这些内容.)
这可能更适合您的用例,因为 EventData
对象还包含有关已执行转换的信息,其中包含源状态的名称:
This might be more suitable for your use case since an EventData
object also contains information about the executed transition which contains the name of the source state:
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)
这篇关于如何将参数传递给`transitions` 库中的 on_enter 回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!