python 中的 FSM 使用转换库时状态不会改变
state do not change in a FSM in python using transitions library
我正在尝试从中复制代码 talk:
class Video:
## Define the states
PLAYING = "playing"
PAUSED = "paused"
STOPPED = "stopped"
def __init__(self,source):
self.source = source
transitions = [
{"trigger":"play","source":self.PAUSED, "dest":self.PLAYING},
{"trigger":"play","source":self.STOPPED, "dest":self.PLAYING},
##
{"trigger":"pause","source":self.PAUSED, "dest":self.PAUSED},
##
{"trigger":"stop","source":self.PAUSED, "dest":self.STOPPED},
{"trigger":"stop","source":self.PLAYING, "dest":self.STOPPED}
]
self.machine = Machine(
model = self,
transitions = transitions,
initial = self.STOPPED)
def pause(self):
print ("pause")
def play(self):
print ("play")
def stop(self):
print ("stop")
但是我调用它,它不起作用:
test = Video("some text")
那个returns一个警告:
2020-09-27 17:25:50,255 [11472] WARNING transitions.core:828: [JupyterRequire] Model already contains an attribute 'play'. Skip binding.
2020-09-27 17:25:50,259 [11472] WARNING transitions.core:828: [JupyterRequire] Model already contains an attribute 'pause'. Skip binding.
2020-09-27 17:25:50,260 [11472] WARNING transitions.core:828: [JupyterRequire] Model already contains an attribute 'stop'. Skip binding.
但主要问题是状态没有改变:
这是原始演讲的代码:
我在此处发布修改后的代码,它可以为您提供预期的输出。为代码格式道歉,我真的很难用这里的标记编辑器。
有问题的代码似乎缺少的东西是
您没有将状态列表传递给 FSM 机器。
另外,看起来机器修改了带有触发器功能的模型。您拥有相同的命名函数似乎覆盖了那些 [1]。我认为触发任何函数的正确方法是使用“after”属性和函数名称。估计以前也会有。
from transitions import Machine
class Video:
## Define the states
PLAYING = "playing"
PAUSED = "paused"
STOPPED = "stopped"
states = [PLAYING, PAUSED, STOPPED]
def __init__(self,source):
self.source = source
transitions = [
{"trigger":"play","source":self.PAUSED, "dest":self.PLAYING, "after": "log_play"},
{"trigger":"play","source":self.STOPPED, "dest":self.PLAYING, "after": "log_play"},
##
{"trigger":"pause","source":self.PAUSED, "dest":self.PAUSED},
##
{"trigger":"stop","source":self.PAUSED, "dest":self.STOPPED},
{"trigger":"stop","source":self.PLAYING, "dest":self.STOPPED}
]
self.machine = Machine(
model = self,
transitions = transitions,
states = self.states,
initial = self.STOPPED)
def log_pause(self):
print ("pause")
def log_play(self):
print ("play")
def log_stop(self):
print ("stop")
参考:
我正在尝试从中复制代码 talk:
class Video:
## Define the states
PLAYING = "playing"
PAUSED = "paused"
STOPPED = "stopped"
def __init__(self,source):
self.source = source
transitions = [
{"trigger":"play","source":self.PAUSED, "dest":self.PLAYING},
{"trigger":"play","source":self.STOPPED, "dest":self.PLAYING},
##
{"trigger":"pause","source":self.PAUSED, "dest":self.PAUSED},
##
{"trigger":"stop","source":self.PAUSED, "dest":self.STOPPED},
{"trigger":"stop","source":self.PLAYING, "dest":self.STOPPED}
]
self.machine = Machine(
model = self,
transitions = transitions,
initial = self.STOPPED)
def pause(self):
print ("pause")
def play(self):
print ("play")
def stop(self):
print ("stop")
但是我调用它,它不起作用:
test = Video("some text")
那个returns一个警告:
2020-09-27 17:25:50,255 [11472] WARNING transitions.core:828: [JupyterRequire] Model already contains an attribute 'play'. Skip binding.
2020-09-27 17:25:50,259 [11472] WARNING transitions.core:828: [JupyterRequire] Model already contains an attribute 'pause'. Skip binding.
2020-09-27 17:25:50,260 [11472] WARNING transitions.core:828: [JupyterRequire] Model already contains an attribute 'stop'. Skip binding.
但主要问题是状态没有改变:
这是原始演讲的代码:
我在此处发布修改后的代码,它可以为您提供预期的输出。为代码格式道歉,我真的很难用这里的标记编辑器。
有问题的代码似乎缺少的东西是
您没有将状态列表传递给 FSM 机器。
另外,看起来机器修改了带有触发器功能的模型。您拥有相同的命名函数似乎覆盖了那些 [1]。我认为触发任何函数的正确方法是使用“after”属性和函数名称。估计以前也会有。
from transitions import Machine class Video: ## Define the states PLAYING = "playing" PAUSED = "paused" STOPPED = "stopped" states = [PLAYING, PAUSED, STOPPED] def __init__(self,source): self.source = source transitions = [ {"trigger":"play","source":self.PAUSED, "dest":self.PLAYING, "after": "log_play"}, {"trigger":"play","source":self.STOPPED, "dest":self.PLAYING, "after": "log_play"}, ## {"trigger":"pause","source":self.PAUSED, "dest":self.PAUSED}, ## {"trigger":"stop","source":self.PAUSED, "dest":self.STOPPED}, {"trigger":"stop","source":self.PLAYING, "dest":self.STOPPED} ] self.machine = Machine( model = self, transitions = transitions, states = self.states, initial = self.STOPPED) def log_pause(self): print ("pause") def log_play(self): print ("play") def log_stop(self): print ("stop")
参考: