3

我正在编写一个简单的国际象棋程序来在 python 3 中练习我的 OOP,并且想知道如何动态更改(在创建类之前)类定义的基类。我的班级结构是这样的。

  • 抽象片类 -> 各种派生片
  • Board 类,由派生的 Pieces 和 8x8 矩阵以及一些方法组成
  • 抽象接口类 -> CLI 或
  • 抽象接口类 -> GUI(也是 Tkinter 的子类)
  • Game 类(用于处理游戏逻辑和主循环),目前有一个 Board 类成员。

我最初将 Game 类实现为具有在init期间定义的接口数据成员,但我发现自己将许多其他内部 Game 数据发送到 Interface 复合成员。我觉得让 Game 类成为任一接口子类的子类会更优雅,这样它就可以直接访问它们的方法(并使它们抽象)。

但是,我想要一个可以动态执行此操作的 Game 类版本,这样我就不必编写两次代码或从两者继承,也不必在运行时决定使用哪个基类。我目前通过将 Game 类嵌套在这样的函数中来完成此操作。

def Game(ui):
    class Game(ui):
        ...
    return Game()

糟糕的命名是我不喜欢这个解决方案的部分原因。我希望能够在不明确使用或承认我正在做任何不寻常的事情的情况下自行调用 Game 类。

有没有办法使用元类或类装饰器来做到这一点?我只能让它们影响类属性,而不是父类。

4

2 回答 2

3

class语句是“语法糖”

type(name, bases, dict)

type您可以使用这样的方式创建这样一个动态类

>>> class ui():
...     def start(self): print("Started!")
... 
>>> Game = type("Game", (ui,), {})
>>> game = Game()
>>> game.start()
Started!
于 2013-05-21T00:12:03.780 回答
3

可以在这里使用一个非常简单的metclass,但这太过分了。您可以根据您想要的任何条件换出您使用的类作为基类:

>>> class Foo: pass
... 
>>> class Bar: pass
... 
>>> x = 3
>>> class Game(Foo if x < 3 else Bar):pass
... 
>>> Game.__bases__
(<class '__main__.Bar'>,)

请注意,这与您所拥有的形式主义并没有什么不同。但是,如果我要使用您的代码,我不会Game在函数中创建类和实例。我会做类似的事情:

def Game_Factory(base):
    class Game(base):
         ...
    return Game

Game1 = Game_Factory(base1)
Game2 = Game_Factory(base2)

game1_instance = Game1()
game2_instance = Game2()

这使您可以更轻松地访问Game该类(而不是需要检查实例来获取它)。

于 2013-05-21T00:12:04.590 回答