如何根据 Python 中的索引仅创建 class 的一个实例?

How can I create only one instance of a class depending on an index in Python?

我有一个函数可以让您通过给定的索引创建自动机的实例。用户从菜单中选择一个选项,所选行的索引决定了要使用的自动机。

def create_automata(idx, board):
    n_automatas = {
        0: GameOfLife(board),
        1: LangtonAnt(board, (board.height // 2) - 4, board.width // 2),
        2: BrianBrain(board),
        3: DayNight(board)
    }

    return n_automatas[idx]

问题是字典已经为每个 class 创建了一个实例。我不希望这样,因为在给定情况下给出的棋盘将不起作用,例如,在 GameOfLife 中,但它会在 BrianBrain 中起作用。最重要的是,如果我要添加更多自动机,dict 将创建我不会使用的实例。

我如何 return 一个自动机而不创建超过我需要的实例(不使用 if/elif 语句)?

一种简单的方法是在字典中存储可调用项而不是实例化对象:

def create_automata(idx, board):
    n_automatas = {
        0: GameOfLife,
        1: lambda board: LangtonAnt(board, (board.height // 2) - 4, board.width // 2),
        2: BrianBrain,
        3: DayNight,
    }

    return n_automatas[idx](board)

请注意,如果您可以将 LangtonAnt 构造函数更改为仅获取板并自行派生其他参数,则此代码会变得更加清晰(如果所有构造函数都具有相同的签名,则无需特地把那个包裹在 lambda).

您可以延迟创建,直到请求自动机。

这就是工厂模式。

由于没有用于创建自动机的统一接口,您可以使用 lambda 来获取板。然而,除了 LangtonAnt 之外,大多数自动机都已经适合这个了:

automatas = {
    0: GameOfLife,
    1: lambda board: LangtonAnt(board, (board.height // 2) - 4, board.width // 2),
    2: BrianBrain,
    3: DayNight
}

return automatas[idx](board)