【问题标题】:TypeError - unbound method ToTransition() must be called with FSM instance as first argument (got str instance instead)TypeError - 必须使用 FSM 实例作为第一个参数调用未绑定的方法 ToTransition()(改为获取 str 实例)
【发布时间】:2018-09-28 11:14:34
【问题描述】:

我有一个有限状态机,它应该随机选择一个状态进入,但是我收到以下类型错误;

必须使用 FSM 实例作为第一个参数调用未绑定的方法 ToTransition()(改为获取 str 实例)

我不确定为什么会这样。启动时,它可以调用第一个状态,但随后失败。任何建议将不胜感激。

from random import randint
from time import clock

##========================================
##TRANSITIONS

class Transition(object):
def __init__(self, toState):
    self.toState = toState

def Execute(self):
    print ("Transitioning...")

##=======================================
##STATES

class State(object):
    def __init__(self, FMS):
        self.FSM = FSM
        self.timer = 0
        self.startTime = 0

    def Enter(self):
        self.timer = randint(0,5)
        self.startTime = int(clock())

    def Execute(self):
        pass

    def Exit(self):
        pass

class CleanDishes(State):
    def __init__(self, FSM):
        super(CleanDishes, self).__init__(FSM)

    def Enter(self):
        print ("Preparing to clean dishes")
        super(CleanDishes, self).Enter()

    def Execute(self):
        print ("Cleaning Dishes.")
        if(self.startTime + self.timer <= clock()):
            if not(randint(1,3) %2):
                self.FSM.ToTransition("toVacuum")
            else:
                self.FSM.ToTransition("toSleep")

    def Exit(self):
        print ("Finished the Dishes.")

class Vacuum(State):
    def __init__(self, FSM):
        super(Vacuum, self).__init__(FSM)

    def Enter(self):
        print ("Preparing to Vacumm")
        super(Vacuum, self).Enter()

    def Execute(self):
        print ("Vacuuming.")
        if(self.startTime + self.timer <= clock()):
            if not(randint(1, 3) %2):
                self.FSM.ToTransition('toSleep')
            else:
                self.FSM.ToTransition('toCleanDishes')

    def Exit(self):
        print ("Finished Vacuuming.")

class Sleep(State):
    def __init__(self, FSM):
        super(Sleep, self).__init__(FSM)

    def Enter(self):
        print ("falling asleep")
        super(Sleep, self).Enter()

    def Execute(self):
        print ("Sleeping.")
        if(self.startTime + self.timer <= clock()):
            if not(randint(1,3) %2):
                self.FSM.ToTransition("toVacuum")
            else:
                self.FSM.ToTransition("toCleanDishes")

    def Exit(self):
        print ("Waking Up.")

##======================================
##FSM

class FSM(object):
    def __init__(self, character):
        self.char = character
        self.states = {}
        self.transitions = {}
        self.curState = None
        self.prevState = None
        self.trans = None

    def AddTransition(self, transName, transition):
        self.transitions[transName] = transition

    def AddState(self, stateName, state):
        self.states[stateName] = state

    def SetState(self, stateName):
        self.prevState = self.curState
        self.curState = self.states[stateName]

    def ToTransition(self, toTrans):
        self.trans = self.transitions[toTrans]

    def Execute(self):
        if(self.trans):
            self.curState.Exit()
            self.trans.Execute()
            self.SetState(self.trans.toState)
            self.curState.Enter()
            self.trans = None
        self.curState.Execute()

##===================================
##IMPLEMENTATION

Char = type("Char", (object,), {})

class RobotMaid(Char):
    def __init__(self):
        self.FSM = FSM(self)

        ##STATES
        self.FSM.AddState("Sleep", Sleep(self.FSM))
        self.FSM.AddState("CleanDishes", CleanDishes(self.FSM))
        self.FSM.AddState("Vacuum", Vacuum(self.FSM))

        ##TRANSISITONS
        self.FSM.AddTransition("toSleep", Transition(Sleep))
        self.FSM.AddTransition("toVacuum", Transition(Vacuum))
        self.FSM.AddTransition("toCleanDishes", Transition(CleanDishes))

        self.FSM.SetState("Vacuum")

    def Execute(self):
        self.FSM.Execute()

if __name__ == '__main__':
    r = RobotMaid()
    for i in range(20):
        startTime = clock()
        timeInterval = 1
        while(startTime + timeInterval > clock()):
            pass
        r.Execute()

【问题讨论】:

    标签: python fsm


    【解决方案1】:

    这里:

    class State(object):
        def __init__(self, FMS):
            self.FSM = FSM
    

    参数名称是“FMS”,但您将 self.FSM 设置为 FSM,然后将其解析为(全局)FSM 类。

    如果您遵循 Python 命名约定(CamelCase 中的类名称,all_lower 中的变量和方法名称)或至少一些一致的命名约定,即您不为类和类使用相同的确切名称,则不会发生这种情况实例...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 2023-04-06
      • 1970-01-01
      • 2017-12-09
      • 2015-12-01
      • 2018-08-12
      相关资源
      最近更新 更多