python - 如何将参数传递给 `transitions` 库中的 on_enter 回调?

标签 python transition state-machine fsm pytransitions

我想使用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' 文档中名为 Passing Data 的部分:

... 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.

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

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。这将改变转换将触发器参数传递给回调的方式:

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 对象还包含有关已执行转换的信息,其中包含源状态的名称:

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)

关于python - 如何将参数传递给 `transitions` 库中的 on_enter 回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68176471/

相关文章:

python 将一个json结构转换为嵌套结构

python - 寻找 manage.py 子命令的来源

javascript - 转换转换的 d3 转换不适用于 DIV

javascript - 将新数据添加到 d3 streamgraph 时的转换

jquery - 模态弹出过渡 - 从按钮弹出?

java - 有限状态机是该用例的正确选择吗?

python - 在 Python 中检测两个图像在视觉上是否相同的快速有效方法

Python广播: how to unleash NumPy speed when filling in a One-Hot vector?

java - IVR 风格的对话系统/工作流程/菜单

hash - 为有限状态自动机接受的语言寻找好的散列函数