本文介绍了如何将参数传递给`transitions` 库中的 on_enter 回调?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 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 回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 12:49
查看更多