仅具有一个实例的Python类:何时创建(单个)类实例以及何时使用该类?


11

给定一个仅实例化一次的Python类,即该类中只有一个对象。我想知道在什么情况下创建单个类实例而不是直接与该类一起工作才有意义。

有一个类似的问题,但重点不同:

  1. 它是关于将全局变量和函数分组为一个类,
  2. 它不是特定于Python的。后者意味着它不考虑(在Python中)类也是对象的事实。

更新:

在Python中,我可以对类和对象执行以下操作:

class A(object):
    pass

A.some_state_var = True
# Then later
A.some_state_var = False


my_a = A()

my_a.some_state_var = True
# Then later
my_a.some_state_var = False

因此,我看不到在类和该类的实例之间进行选择如何与状态有关(在Python中)。我可以通过两者之一来保持状态。

此外,创建我的类/类实例的动机与执行Singleton要求无关。

另外,创建新的Type并不需要太多。

这样做的动机是将相关的代码和数据进行分组,并为其提供接口。这就是为什么我最初在类图中将其建模为类的原因。仅当涉及到实现时,我才开始怀疑是否要实例化此类。

Answers:


16

给定一个仅实例化一次的Python类,即该类中只有一个对象。我想知道在什么情况下创建单个类实例而不是直接与该类一起工作才有意义。

就是这样:

class Singleton:
    '''don't bother instantiating me'''
    clsvar1 = 'foo'

    @classmethod
    def foobar(cls, *args, **kwargs):
        if condition():
            cls.clsvar1 = 'bar'

与这个?

class Singleton:
    '''instantiate and use me'''
    def __init__(self):
        self.var1 = 'foo'

    def foobar(self, *args, **kwargs):
        if condition():
            self.var1 = 'bar'

建议

我绝对希望将其实例化。当您创建“事物类型”时,意味着您创建了该类型的事物。

这样做的动机是将相关的代码和数据进行分组,并为其提供接口。

就是说,为什么不只使用模块,因为您只需要一个名称空间?模块是单例的,是与组有关的代码和数据,这有点简单,可能会被认为是更Pythonic的:

var1 ='foo'

def foobar(*args, **kwargs):
    global var1
    if condition():
        var1 = 'bar'

因此,用法将是:

from modules.singleton import Singleton
Singleton.foobar()

要么

from modules.singleton import Singleton
the_singleton = Singleton()
the_singleton.foobar()

做这个:

from modules import singleton
singleton.foobar()

3
感谢您的回答。您是否真的建议为每个函数(包括变量)创建一个新模块(一个新的.py文件)?这可能会导致许多小的.py文件。还是将所有(至少在某种程度上相关的)“无类”功能和变量归为一个模块?
langlauf.io 2015年

再说一遍:您编写“因为您想要的只是一个名称空间”。我想要的是将相关代码(即函数和数据)集中在一个地方,并有一个接口。创建“类型”并不需要太多。在设计过程中,无论如何都会在类图中生成一个类,不是吗?
langlauf.io 2015年

2

我想知道在什么情况下创建单个类实例而不是直接与该类一起工作才有意义。

如果您投入太多,这就是会引起宗教战争的事情之一。

但是总的来说,我经常看到的一种做法是,类方法只应与创建该类的实例有关。

如果您考虑一个类是什么,它的目的/行为是什么,那么这是有道理的。类的目的是创建基于自身的对象的实例。这是也可以建造建筑物的蓝图。“用户”类创建“用户”对象。“狗”类创建“狗”对象等

给出这是一个有意义的类的行为,那么添加到类“ X”的方法将涉及创建“ x”对象。

因此,即使您只需要一个“ x”对象,也应该实例化它。

向X类添加与创建“ x”对象的实例无关的方法会导致混淆意外代码。在现实世界中,当然有无数的例子,无论如何人们都这样做了,但是就像我说的那样,这条道路导致了宗教战争。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.