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.

但主要问题是状态没有改变:

这是原始演讲的代码:

我在此处发布修改后的代码,它可以为您提供预期的输出。为代码格式道歉,我真的很难用这里的标记编辑器。

有问题的代码似乎缺少的东西是

  1. 您没有将状态列表传递给 FSM 机器。

  2. 另外,看起来机器修改了带有触发器功能的模型。您拥有相同的命名函数似乎覆盖了那些 [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")
    

参考:

  1. https://github.com/pytransitions/transitions/blob/master/transitions/core.py#L594