python - 调用对象的状态特定代码块的最有效方法是什么?

标签 python python-3.x performance

我有一个很大的游戏对象列表 (30-50),它们按照 sudo 顺序在 5-7 种状态之间变化,从而从根本上改变了它们的行为。

我最初的天真的方法是给每个游戏对象一个状态变量,然后每个 Action 命令都会通过 if-else block 来找到与状态相对应的正确 Action 。

选项 1(朴素方法)

class Bot:
    def action(self):
        if self.state == 1:
            action1()
            if condition1_to_2():
                self.state = 2
        elif self.state == 2:
            action2()
        #...

list_of_bots = [Bot(), Bot(), ...]

for bot in list_of_bots:
    bot.action()

但我想,有 50 个游戏对象,这种 if-else 遍历不会开始占用大量时间吗?

我不能通过直接声明正确的代码来加快性能吗?

我能想到实现这一点的唯一方法是使用继承(接口(interface)或子类)并使每个游戏对象的每个游戏状态成为自己的子类,每次更改状态时都会销毁并创建一个新对象。

选项 2(继承)

class Bot:
    def action(): raise NotImplementedError

class Bot1(Bot):
    def action():
       action1()

class Bot2(Bot):
    def action():
       action2()
#...

list_of_bots = [Bot1(), Bot2(), ...]

for bot in list_of_bots:
    bot.action()

这样每个游戏对象就不必在游戏的每个周期中检查它的状态,从而每个周期节省 300 次操作。

我唯一的问题是,制作这么多新类(class)感觉有点矫枉过正。是否有更紧凑但同样有效的解决方案来解决这个问题?

我想到了状态字典或列表(假设它们提供 O(1) 访问时间),但是如何将列表链接到代码块?

选项 3(不可能?)

class Bot:
    def __init__(self):
       self.action_list = [action1(), action2(), ...]
       self.state = 1

    def action():
        self.action_list[self.state]

该解决方案必须在原始 python3 中完成(无需 pip 安装)。

最佳答案

您的选项 3 可以使用函数引用,但是我不确定这个程序结构是否最好使用。但要完成存储函数引用列表,您可以这样做:

class Bot:
    def __init__(self, game_map):
       self.action_list = [self.action1, self.action2]  # Stores function references
       self.state = 1
       self.game_map = game_map  # Pass in game_map object that the class can use

    def action(self):
        self.action_list[self.state]()  # Calls function reference

    def action1(self):
        # Does something

    def action2(self):
        # Does something

编辑:我添加了一个示例,说明如何传递您在评论中提到的 game_map 对象。然后,您可以在操作函数中的任何位置使用 self.game_map,只要您每次修改该 map 而不是创建新 map ,这将是您的游戏 Controller 正在更新的同一对象。

关于python - 调用对象的状态特定代码块的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53013141/

相关文章:

python - 使用递归计算列表的数量?

python - 如何在数据框列中 append 值

python - 输出总是一个空列表

android - 配置 WebRTC android 以获得最低延迟

mysql - 为什么连接到 MySQL 服务器这么慢?

python - 在并发环境中追加到文件末尾

Python pandas 交叉选择相当于 .loc 和切片

django - django 2.0 中的错误 404 静态文件

python - 是否可以用装饰器修改类

performance - 我应该使用 Varnish 而不是 nginx 吗?