如何高效地链接多个类

3 投票
2 回答
12778 浏览
提问于 2025-04-18 06:22

背景: 我正在用Python开发一个游戏,为了保持代码的整洁和有序,我创建了一个文件夹,里面有多个Python文件,每个文件里都有一个大类,比如“MapEngine”(地图引擎)或“NPCEngine”(NPC引擎)。

在main.py文件中,我从每个文件加载这些类,并通过一个“Game”类把它们连接在一起,像这样:

from folder import *

class Game:

    def __init__(self):
        self.MapEngine = MapEngine.MapEngine()
        ...

    def loop(self):
        ...

由于像“CollisionEngine”(碰撞引擎)这样的类需要从其他类(比如“MapEngine”)获取数据,我通常会在前者(即CollisionEngine)中给后者(即MapEngine)分配一些变量,以便使用MapEngine加载的地图数据或功能:

class CollisionEngine:

    def __init__(self, MapClass, ...):
        self.MapEngine = MapClass

问题: 但是,由于许多类需要相互连接,过了一段时间后,我发现很难搞清楚应该先加载哪个类来分配变量。此外,像“EventEngine”(事件引擎)这样的类需要访问其他所有类。我的代码变得难以阅读,当两个类彼此同样重要时,我也很困惑。

疑问: 我听说过类的继承,但我觉得在这里不适用,因为每个类的功能都很不同。那么,有没有办法优雅地将每个类连接在一起,就像它们都是一个大类的一部分?换句话说,有没有办法在一个类内部引用其他类的变量?

(我的想法:也许我可以写一个叫“Request”的类,它可以作为一个顶层的类管理器。不过,我觉得我可能需要使用像exec()或eval()这样的函数,这些函数效率不高,而且有点危险。)

这是我的第一次发帖,我尽量表达得清楚明了,如果有不明白的地方请问我,谢谢你的回复!

2 个回答

1

考虑把你的项目分成几个层次,这样可以帮助你更好地组织代码,让导入的内容看起来更自然。

这个原则是,代码的下层“蛋糕”不应该依赖于(也就是不应该导入)上层的代码。

举个例子,你可以有一个基础层,这里包含一些常用的数据结构、工具类和算法,这些在你项目的不同层次中都会用到。

接着,你可以有一个模型层,这一层依赖于基础层(也就是使用基础层中的数据结构、工具和算法),但不依赖于其他层。模型层提供了领域内对象的模型。

然后,你可能会有一个游戏层,这一层依赖于模型层(所以在游戏层中的模块可以从模型层导入内容,但反过来就不行)。

0

经过多次尝试,我找到了一种(虽然不太完美)解决我问题的方法。当然,正如eddiewould所建议的,我会对我的代码进行更好的组织,并增加多个层级。不过,如果你想让多个类相互关联,只需在主类中添加一个变量(这个主类会调用所有其他类)到每个类中。我觉得用代码示例来说明会更清楚:

main.py
engine_folder
----> engine_1.py
----> engine_2.py

在main.py中,engine_1和engine_2被加载:

from engine_folder import engine_1, engine_2

class game:

  def __init__(self):
      self.engine_1 = engine_1.engine(self, ...)
      self.engine_2 = engine_2.engine(self, ...)
      #where engine_1.engine and engine_2.engine are
      #two classes that need to transfer data between
      #each other

  def run(self):
      self.engine_1.run()
      self.engine_2.run()

注意engine_1.engine的第一个参数是self,这个self指的是调用这个类的顶层类。现在,在engine_1中,如果我们想打印engine_2中的一个变量,类的写法大概是这样的:

class engine:

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

  def run(self):
      print self.top_level_class.engine_2.random_var

这样写是很不错的(虽然print self.top_level_class.engine_2.random_var这个写法有点长),但相比于下面这样的写法:

class EventEngine:

  def __init__(self, Camera_Class, Map_Class, Character_Class, Skill_Class,
               Interface_Class, Sprite_Class, Dialog_Class, Game_Class,
               Item_Class):
      self.ItemEngine = Item_Class
      self.GameEngine = Game_Class
      self.DialogEngine = Dialog_Class
      self.SpriteEngine = Sprite_Class
      self.SkillEngine = Skill_Class
      self.CameraEngine = Camera_Class
      self.MapEngine = Map_Class
      self.CharacterEngine = Character_Class
      self.IEngine = Interface_Class

新的版本:

class EventEngine:
  def __init__(self, top_level_class):
      self.top = top_level_class
      #a var from Map_Class can be called as such:
      #self.top.MapEngine.map[0][1]
      #and I can call variables from every class, not only those I 
      #have loaded like before

要好得多,代码也更简洁。

撰写回答