在python中为有限状态机分配函数作为变量

Fre*_*Bag 3 python oop python-3.x

我正在尝试用 python 制作游戏,但遇到了根据游戏中的动作让对象切换状态的问题。

我发现最好的方法是使用某种方法将函数(对象的状态)定义为变量,并根据操作赋予对象一个状态。不幸的是,我不确定这是否可行,或者在谈到这个主题时可能有一个我还没有学习的概念。如果有人可以为我的问题提供解决方案,或者只是指出我学习解决问题的方法的方向。

有没有办法将某些函数/方法与名称相关联并避免多个if语句?

class stateUser:

    def __init__(self,state):
        self.state = state

    def executeState(self):
        if self.state == "Print Something":
            self.printSomething()
        elif self.state == "Not Print Something":
            self.dontPrint()
        else:
            self.notUnderstand()
        '''
            would like this function to simply call
            a function that is defined as the object's state,
            instead of using a bunch of if statements
        '''

    def printSomething(self):
        print("Something")

    def dontPrint(self):
        print("No")

    def notUnderstand(self):
        print("I didn't understand that")

runner = stateUser(None)
a = True
while a:
    runner.state = input("Enter the state you would like to change to\n")

    runner.executeState()
Run Code Online (Sandbox Code Playgroud)

上面的代码显然不是我正在制作的游戏项目的直接片段,而是我输入的与情况非常相似的东西。任何意见或解决方案将不胜感激。

PRM*_*reu 5

您可以创建一个 dict 来存储所有操作和匹配的函数/方法。

然后您只需要使用dict.get()来查找用户给出的匹配操作或使用默认值self.notUnderstand(作为第二个参数传递):

dict 结构允许将函数存储为引用,而无需(),因此您只需在 result 上添加这些括号action。(或直接将其添加到self.actions.get(self.state, self.notUnderstand)()以保存一行)。

class stateUser:

    def __init__(self,state):
        self.state = state
        self.actions = {
            'printSomething': self.printSomething,
            'Not Print Something': self.dontPrint,
        }

    def executeState(self):
        action = self.actions.get(self.state, self.notUnderstand)
        action()
Run Code Online (Sandbox Code Playgroud)

另一个优点是您可以使用此 dict 的键为用户提供选择:

while a:
    runner.state = input("Enter the state you would like to change to\n"+
                         ' - '.join(runner.actions.keys()))

    runner.executeState()

#>>> Enter the state you would like to change to
#printSomething - Not Print Something
Run Code Online (Sandbox Code Playgroud)