在模块和类之间进行选择

时间:2009-03-01 18:00:39

标签: python oop module

在我的应用程序中,我必须维护一些全局应用程序状态和全局应用程序范围的方法,如当前连接的用户,答案总数,创建应用程序配置文件等。有两种选择:

  1. 创建一个单独的appstate.py文件,其中包含带有函数的全局变量。它看起来很好,但似乎我在代码的清晰度中缺少某些东西

  2. 在appstate.py文件中创建具有类函数的类AppState,所有其他模块都由其特定作业定义。看起来很好。但现在我必须编写更长的行,如appstate.AppState.get_user_list()。而且,这些方法并没有太多相互关联。我可以创建单独的类,但这将是太多的类。

  3. 编辑:如果我使用类,我将使用classmethods。我认为不需要将类实例化为对象。

7 个答案:

答案 0 :(得分:23)

听起来像经典的难题: - )。

在Python中,如果这是最好的方法,选择使用模块没有任何肮脏或可耻。毕竟,模块,函数等实际上是该语言中的一等公民,并提供许多其他编程语言仅通过使用对象提供的内省和属性。

你描述你的选择的方式,听起来有点像你在这种情况下对基于类的方法并不太疯狂。

我不知道您是否使用过Django框架,但如果没有,请查看有关如何处理设置的文档。这些是应用程序范围的,它们在模块中定义,并且可在全球范围内使用。它解析选项并在全球范围内公开它们的方式非常优雅,您可能会发现这种方法可以满足您的需求。

答案 1 :(得分:5)

如果您将应用程序状态存储在AppState的实例中,则第二种方法与第一种方法明显不同,在这种情况下,您的投诉不适用。如果您只是在类中存储东西并使用静态/类方法,那么您的类与模块没什么区别,而实际上将它作为模块实际上是pythonic。

答案 2 :(得分:3)

第二种方法似乎更好。我只使用第一个配置文件或其他东西。

无论如何,为了避免这个问题你总是可以:

from myapp.appstate import AppState

这样你就不必再写长线了。

答案 3 :(得分:1)

为什么不选择该类的实例?这样你甚至可以在以后运行2个不同的“会话”,具体取决于你使用的实例。它可能会使它更灵活。也许可以在模块中添加一些方法get_appstate(),这样它就可以对类进行一次实例化。稍后,如果您可能需要多个实例,则可以更改此方法以最终获取参数并使用某些字典等来存储这些实例。

你也可以使用属性修饰器btw来使事物更具可读性,并且可以灵活地存储你想要它存储的方式和位置。

我同意使用模块方法而不是classmethods会更加pythonic。

顺便说一下,我并不是一个狂热的粉丝,因为某些“神奇”让全球的东西可用。我宁愿使用一些显式调用来获取该信息。然后我知道事情的来源以及如何在事情失败时调试它。

答案 4 :(得分:1)

考虑这个例子:

configuration
|
+-> graphics
|   |
|   +-> 3D
|   |
|   +-> 2D
|
+-> sound

真正的问题是:这个层次结构中的类和模块之间有什么区别,因为它可以用两种方法表示?

类表示类型。如果使用类而不是模块实现解决方案,则可以检查图形对象的正确类型,但是编写通用图形函数。

使用类可以生成参数化值。这意味着可以使用构造函数以不同方式初始化 sound 类,但很难初始化具有不同参数的模块。

关键是,你真的与建模的观点有所不同。

答案 5 :(得分:0)

我会选择类路由,因为它会更好地组织你的代码。请记住,为了便于阅读,您可以这样做:

from appstate import AppSate

答案 6 :(得分:0)

我肯定会选择第二个选项:已经使用了第一个选项,我现在被迫重构,因为我的应用程序已经发展并且必须支持更多的模块化结构,所以我现在需要处理多个同时的“配置” ”。

第二种方法是,IMO,更灵活,面向未来。为避免使用较长的代码行,您可以使用from appstate import AppState而不是import appstate