如何将参数传递给`transitions` 库中的 on_enter 回调? [英] How to pass parameters to on_enter callbacks in `transitions` library?

查看:45
本文介绍了如何将参数传递给`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() 时创建)[...] 您可以将任意数量的参数传递给触发器.这种方法有一个重要的限制:状态转换触发的每个回调函数都必须能够处理所有参数.

... you can pass any positional or keyword arguments directly to the trigger methods (created when you call add_transition()) [...] You can pass any number of arguments you like to the trigger. There is one important limitation to this approach: every callback function triggered by the state transition must be able to handle all of the arguments.

对于您的特定示例,这可能如下所示:

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 对象还维护与事件关联的源状态、模型、转换、机器和触发器的内部引用,以防您需要访问这些内容.)

If you set send_event=True at Machine initialization, all arguments to the triggers will be wrapped in an EventData instance and passed on to every callback. (The EventData object also maintains internal references to the source state, model, transition, machine, and trigger associated with the event, in case you need to access these for anything.)

这可能更适合您的用例,因为 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 回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆