如何将我的Python代码组织成多个类?

时间:2012-05-08 13:17:59

标签: python class design-patterns

我最近被告知我应该将我的代码保存在单独的文件中;例如main.pyengine.pysettings.py等。虽然这肯定会带来诸多好处,比如更容易管理,可扩展性等等,但对我来说似乎有太多缺点......

例如,如果我有一个名为settings.py的脚本,其中定义了屏幕对象的大小,模拟的速度和各种对象的颜色,如果需要这些变量,我该怎么办?我的engine.py脚本和我的main.py脚本?我在两个脚本中都导入了两次吗?看起来相当混乱。如果engine.py脚本中的某些类需要main.py的代码,该怎么办?

让我告诉你具体情况......

我的main.py脚本本身导入Pygame,初始化它,依此类推。它曾经有一个表示屏幕上对象的类,该类有一个方法draw,它只是调用Pygame绘制函数。现在,当我把这个类放在我的engine.py脚本中时,事情就不再有效了,因为Pygame在那里不存在!我最终在settings.py中导入engine.py和Pygame,然后将引擎导入main.py,但是它更像是初始化程序而不是引擎......有没有办法处理像这样的事情,如一般指导线?

6 个答案:

答案 0 :(得分:3)

以下是导入的官方PEP指南:http://www.python.org/dev/peps/pep-0008/#imports

另请参阅此StackOverflow问题:What are good rules of thumb for Python imports?

您可以从多个类中导入变量而不会出现问题,但您应该尝试构建代码,以便不循环导入内容。 Circular import dependency in Python

答案 1 :(得分:1)

你应该看看这个模型,这可能有助于你理解事物。 我认为这是最适合你想做的事情

Model-View-Controller

这里还有一些文档: http://www.wkoorts.com/wkblog/2007/12/23/mvc-design-patterns-with-python-links/

在这种情况下,进口看起来应该是合乎逻辑且必要的。 我想补充一点,就是你已经对你的3个文件做了大致的事情。

答案 2 :(得分:1)

不是答案,但是:

settings.py应该是settings.ini,您应该使用ConfigParser阅读它。阅读配置文件一次,并在模块之间共享结果ConfigParser.RawConfigParser

答案 3 :(得分:1)

其他语言(尤其是Java,其中编译器几乎强制要求)的常见做法是每个类有一个文件。

至于你提到的文件间依赖关系,你应该考虑避免使用全局变量。

这是另一个更好地回答你问题的相关问题。

How many Python classes should I put in one file?

答案 4 :(得分:1)

将模块导入多个其他模块并不麻烦。与具有数千行代码的模块相比,它更清晰

循环导入确实存在问题。但是你的情况听起来并不像循环导入问题。你说“现在,当我把这个类放在我的engine.py脚本中时,事情就不再起作用了,因为Pygame在那里不存在!我最终在engine.py中导入settings.py和Pygame,然后导入引擎进入main.py“。

为什么不能将课程放在engine.py中,然后将其导入main.py?一个非常简单的方法是将回调传递给你的类:

# engine.py
...
class ClassWithDraw(Subclass):
    def __init__(self, draw_callback):
        ...
        self._draw_func = draw_callback
        ...
    def draw(self):
        self._draw_func()

# main.py

from engine import ClassWithDraw
drawer = ClassWithDraw(drawfunc)

这种方法的好处在于,对象实际上只对一件事负责:它自己的状态。实际上,对于这个对象来说,根本没有draw方法可能更有意义;或者它可以有一个draw_hook,可以在必要时调用它来获取可绘制数据,另一个外部绘图函数可以调用它。

另一种方法是为Pygame创建一个完全独立的模块。我对Pygame知之甚少,所以有可能这不起作用,但是说你有一个处理Pygame初始化和状态的模块。您可以在main中将其初始化一次,然后将其导入到您想要的任何位置。

答案 5 :(得分:0)

您可以在settings.py中的任何需要的模块中导入符号。这就是概念。实际问题是当您进行循环导入时。例如如果engine.py中需要main.py内的符号,反之亦然,该怎么办?在这种情况下,一个常见的模式是在第三个模块中打破这些依赖关系,main.pyengine.py可以从中导入,而没有任何问题。