14

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.

0

2 Answers 2

18

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()
2
  • 4
    Thanks for your answer. Would you really suggest creating a new module (a new .py file) for every function (incl. variables)? This could result in many small .py files. Or would you group all (at least somehow related) "class-less" functions and variables in one module? Commented Aug 5, 2015 at 6:15
  • One more remark: You write "since all you want is a namespace". What I want is to group related code, i.e. functions and data, in one place, and have an interface to it. It is not so much about creating a "Type". During design, this would result in a class in a class diagram anyway, wouldn't it? Commented Aug 5, 2015 at 6:21
4

I was wondering in which cases it makes sense to create a single class instance instead of working directly with the class instead.

This is one of those things that will cause a religious war if you get into it to much.

But in general a practice that I have seen many times is that class methods should concern themselves only with creating instances of that class.

If you think about what a class is, what its purpose/behaviour is, then this makes sense. The purpose of a class is to create instances of objects that are based on itself. It is a blueprint that can also build the building. A "User" class creates "user" objects. A "Dog" class creates "dog" objects etc etc

Give this is the behaviour of a class it makes sense then that methods you add to the class "X" will concern themselves with creating "x" objects.

So even if you are only ever going to need one "x" object you should still instanciate it.

Adding methods to the X class that are not related to creating instances of "x" objects can lead to confusing unexpected code. There are of course tons of examples in the real world where people have done this anyway, but like I said that path leads to religious war.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.