5

我问的是关于 Python 的这个问题,尽管它可能适用于大多数 OOP 语言。

当我只希望在任何程序中只使用一次数据模型时,我可以使用类/静态方法和属性创建一个类,或者只创建一个常规类并将其实例化一次,然后只使用那个副本。在这种情况下,哪种方法更好,为什么?

使用 python,我还可以编写一个模块并像使用类一样使用它。在这种情况下,哪种方式更好,为什么?

示例:我想要一个中央数据结构来访问/保存数据到文件。

模块方式:

数据.py

attributes = something
...
def save():
...

主文件

import data
data.x = something
...
data.save()

上课方式:

class Data:
    attributes = something
    @classmethod
    def save(cls):

Data.x = something
Data.save()

实例方式

class Data:
    def save(self):

data = Data()
data.x = something
data.save()
4

2 回答 2

5

模块旨在将公共结构包含在“命名空间”中。但实际上在 python 中,模块只是一个文件,您可以根据需要组织它们。有些人将很多功能放在一个模块中。有些人将它们分散在包或子包中。取决于您想要的可重用性。如果一个模块有大量的依赖项,而您只想重用一小部分,那么拆分它们是有意义的。

类允许您定义可以作为子类型继承的类型。它们还允许您为该类的每个实例定义一个状态。

当你的类没有状态,只有静态方法/类方法时,你可能不需要一个类。你只需要函数。

此外,您不能创建模块并像使用类一样使用它。模块不能有子类。它们只有一个基本模块 init 加载一次,然后是一个对象范围。

如果你所追求的是常量,这意味着它们在应用程序的生命周期中定义一次,那么只需创建一个带有一堆原始类型(如字符串、字典和列表)的 constants.py 模块。

于 2012-07-26T05:50:17.260 回答
3

标准随机模块实现有一个很好的设计,它显示了模块级实例的创建和使用,而不会强制任何用户使用单例。

例如,如果我称它为random.random()使用在导入时初始化的 Random 类的隐藏实例。如果我对默认值不满意,我可以

my_random = random.Random()
my_random.seed('not needed but illustrative seed call')
coin_toss = my_random.random()

然后有一个不与隐藏实例共享状态的生成器。如果您对这种方法感兴趣,请阅读random.py有据可查的文档;只有几行相关的代码并不那么棘手。

这种方法为单例提供了一个有趣的 Pythonic 转折:在导入时自动构建一个,但如果我愿意,不要阻止我实例化更多。

于 2012-07-26T10:50:37.680 回答