Python – When to Create a Single Class Instance vs Working with the Class

class-designdesignobject-orientedobject-oriented-designpython

Given a Python class which will be instantiated only once, i.e. there will be only one object of the class. I was wondering in which cases it makes sense to create a single class instance instead of working directly with the class instead.

There is a similar question, but it has a different focus:

  1. it is about grouping global variables and functions into a class and
  2. It isn't Python-specific. The latter means it does not consider the fact that (in Python) classes are objects too.

UPDATE:

In Python, I can do the following with both classes and objects:

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

So I don't see how the choice between a class and an instance of that class is about state (in Python). I can maintain a state with either of the two.

Furthermore, the motivation to create my class / class instance is not about enforcing a Singleton requirement.

Also, it is not so much about creating a new Type.

The motivation is to group related code and data and having an interface to it. This is why I initially modeled it as a class in a class diagram. Only when it came to the implementation I started wondering whether to instantiate this class or not.

Best Answer

Given a Python class which will be instantiated only once, i.e. there will be only one object of the class. I was wondering in which cases it makes sense to create a single class instance instead of working directly with the class instead.

So it's this:

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

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

versus this?

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

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

Recommendation

I definitely would prefer the one that's intended to be instantiated. When you create a "type of thing" that implies that you create things of that type.

The motivation is to group related code and data and having an interface to it.

That said, why not just use a module since all you want is a namespace? Modules are singletons, group related code and data, and this is a bit simpler and probably would be considered more Pythonic:

var1 ='foo'

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

So the usage would be instead of:

from modules.singleton import Singleton
Singleton.foobar()

or

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

do this:

from modules import singleton
singleton.foobar()
Related Topic