问题描述
我想使用 transitions,需要一个我在文档中找不到的相当琐碎的功能,我想知道它是否已实现:
我想在某个状态上定义一个 DOCKER_TAG := ..
回调,但要向该回调传递一个参数。至少要知道我是从哪个州进入该州。
来自文档:
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}")
参数并自己维护它。
我正在寻找内置的东西。
解决方法
transitions
'文档中名为 Passing Data 的部分:
...您可以将任何位置或关键字参数直接传递给触发器方法(在调用 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,initial='solid',send_event=True)
lump.sublimate(param=42)