1

Currently I'm using a rather simplistic implementation of a singleton. However, I've never seen anything like this suggested on the web, which leads me to believe there might be something wrong with it...

class Singleton:
    def __init__():
        raise ...

    @staticmethod
    def some():
        pass

    @staticmethod
    def another():
        pass

Are there any disadvantages to this implementation of a singleton (making all class members static). It is somewhat similar to using modules as singletons, except you wrap everything in a class.


Edit: I know about other ways to implement singletons in Python. What I don't like about them is that none of them are explicit (which goes against the Python zen):

Since I do a = Class() instead of something like a = Class.Instance(), it is not obvious that I'm dealing with on object with shared state (see note #1). If all members are static I at least have Class.someMethod() which kinda sorta suggests it's a singleton. What I don't like about this approach is that you can't use constructors and destructors, which removes the major advantage that singletons have over free functions, which is what you can do when they are created and destroyed (see note #2).

Note #1: I know I shouldn't care about the singleton's state (if I do, then it shouldn't be a singleton in the first place). I still want it to be explicit about what kind of class it is.

Note #2: When you create a singleton you could do some instantiation in its constructor. For example, in a singleton that deals with the graphics library, you could initialize the library in the constrctor. This way instantiation and deinstantiation happen automatically in the sinleton's constructors and destructor.
Or in a ResourceManager: the destructor could check if upon its destruction there still are resources in memory and act accordingly.
If you use free functions instead of singletons you have to do all of this by hand.

Community
  • 1
  • 1
Paul Manta
  • 30,618
  • 31
  • 128
  • 208
  • 2
    This is just a namespace not a singleton. Use `classmethod`s and it would be a singleton. "Wrong with it?" Nothing, really. But people can't treat it like a normal class, they can't instantiate it, while all the other versions you've seen can be called and simulate -- or actually perform -- instantiation. – agf Aug 26 '11 at 16:11
  • @agf Thanks. Your comment would actually be a pretty good answer. :) – Paul Manta Aug 26 '11 at 17:41
  • I hit my rep goal so I'm taking a break from posting answers, I can be lazy in comments, where I often feel a need to give a complete answer. Also see http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python for another Python / singleton question. – agf Aug 26 '11 at 18:23

5 Answers5

11

Yeah, it's a singleton, that's what's wrong with it. If you're going to make all methods static, don't bother making a class at all, just use free functions.

Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224
  • Replace the class with namespace so you keep the hierarchy. – Lee Louviere Aug 26 '11 at 15:55
  • 1
    @Cat I was the downvoter, and I was planning on posting a comment when I had time... I downvoted because of your absolute statement that singletons are always bad. Think about cases when you want to automate (de)instantiation of a module (like a graphics module); singletons are great for that. – Paul Manta Aug 26 '11 at 17:37
  • @Cat Making absolute statements is almost always wrong and irrational. – Paul Manta Aug 26 '11 at 17:39
  • 1
    @Paul: No, just no. For reliable destruction you need a context manager or scope-based resource management, not singletons, that's a silly idea. Not to mention dependency hiding, uncontrolled construction, almost always idiotic restriction to only one instance, and ugh, screw it, I'm not going to repeat myself again. Feel free to come by to Lounge for some singleton bashing. – Cat Plus Plus Aug 26 '11 at 18:13
  • Generalizations aside, this answers the question rather clearly. If you don't want an instance of the class (see: `def __init__(self): raise`), then you don't want a class; this isn't even a singleton, since there is no single instance. It's more of a zeroton. This answer is better solution for that situation. – SingleNegationElimination Aug 26 '11 at 18:18
  • 2
    @Paul: Singletons _are_ [always bad](http://jalf.dk/blog/2010/03/singletons-solving-problems-you-didnt-know-you-never-had-since-1995/). – sbi Aug 26 '11 at 18:44
  • @sbi Damint, I hate it when people use 'always' in discutions that are supposed to be rational. – Paul Manta Aug 26 '11 at 18:46
  • 1
    @Paul I read that transcript and I have to say your argument is confused and you don't even seem to realise it. "if a singleton has a state you care about, you're doing it wrong". If it **doesn't** have a state you care about, then there is no reason for it to exist; objects exist for the purpose of preserving state. If there is only functionality, then there is only a need for... functions. – Karl Knechtel Aug 26 '11 at 18:54
  • 1
    "if you artifically limit a class to be a singleton you're again doing it wrong" But Cat Plus Plus didn't say anything about "artificially limiting a class to be a singleton". Rather, the point is that a singleton is, by definition, arbitrarily limited to have only one instance. This restriction doesn't generally accomplish anything. – Karl Knechtel Aug 26 '11 at 18:56
  • @Karl Read the bit about how I use its contructor/destructor to automate library initialization/deinitialization. (Reading it again, I realize I wasn't ver clear, sorry about that.) – Paul Manta Aug 26 '11 at 18:56
  • 1
    "i'm not hiding dependencies, what makes you think that?" Uh, the fact that you're referring to a global singleton from where you like, instead of passing an object around as a parameter. Dependencies are hidden where they are not part of the interface. A function that receives information from its parameters is using dependencies from the interface. A function that receives information from the global context is using hidden dependencies. You can't determine that the function depends upon the singleton except by actually inspecting the code of the function. That's as hidden it gets, really. – Karl Knechtel Aug 26 '11 at 18:57
  • @KarlKnechtel let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2905/discussion-between-paul-and-karl-knechtel) – Paul Manta Aug 26 '11 at 18:58
  • The answer to this question is also interesting... ;) http://stackoverflow.com/questions/46541 – Paul Manta Aug 26 '11 at 19:33
  • @Paul: I'm not going to be drawn into that chat, repeating what you were already told. Assume that we know of Singletons for years (I was programming before the GoF coined the term, and read the book - enthusiastically - shortly after it was published), used these beasts for a decade, and, after all those years, came to the conclusion they are bad. Not try to understand why. – sbi Aug 26 '11 at 21:41
  • @sbi I'm really curious how you used them before and what happened that made you realize they aren't good for anything. – Paul Manta Aug 27 '11 at 05:36
  • @Paul: All the arguments are already listed in jalf's blog entry, linked above, but: Poisoned by the GoF's advice, we used Singletons extensively in a several MLoC codebase that keeps growing since >10 years. I left years ago, thinking that, when the requirement to make the thing multi-threaded comes in (and it would, that was clear 10 years ago), all hell would break lose. I still meet some of those guys once in a while for a beer or two, and it seems my prediction was right: They now _are_ in that hell, and Singletons are among the bad things they need to get rid of to meet the requirement. – sbi Aug 27 '11 at 11:08
  • Oh, and I forgot to mention testing code using Singletons had always been a bad problem. As I said, it's all there, in jalf's blog, explained way more eloquently than I ever could. – sbi Aug 27 '11 at 11:09
2

That's not a singleton. It's a stateless global collection of methods, wrapped in a type.

Nothing inherently wrong with it, unless you believe that it is a singleton.

Singleton implies one instance only.

Lee Louviere
  • 5,162
  • 30
  • 54
  • 3
    This is Python. We care not about type, but function. It functions as a singleton, so _it is a singleton_. – agf Aug 26 '11 at 16:09
  • @agf No, it functions as a singleton, so it can be *treated* as a singleton -- this does *not* make it a singleton. – Ethan Furman Sep 11 '11 at 20:03
1

It's impossible to mock, so it's hard to test.

That's what's wrong to it.

Actually having 1 object of a testable class is considered better practice.

xtofl
  • 40,723
  • 12
  • 105
  • 192
1

We are borg! This way state is shared across every instance of the object.

class Borg(object):
    state = {}
    def __init__(self):
        self.__dict__ = self.state

a = Borg()
a.a = 34
b = Borg()
print b.a
c = Borg()
c.c = "haha"
print a.c

Just to quote the original

Jakob Bowyer
  • 33,878
  • 8
  • 76
  • 91
  • 2
    While this is an alternative and arguably better solution, this answer doesn't really show anything wrong about OP's approach, does it? –  Aug 26 '11 at 16:00
  • But it does provide an entirely alternate option that looks to most, more pythonic. – Jakob Bowyer Aug 26 '11 at 16:01
  • True (I basically said the same thing too). But the question was something entirely different. –  Aug 26 '11 at 16:06
1

A singleton is a class which creates the same instance each time the constructor is called. Your class has no constructor, so it can not be a singleton.

The borg pattern is something different, here each instance shares the same attributes. Alex Martelli, the inventor of the borg pattern, gave a talk at the 2011 Europython where he told that Guido van Russom dislikes the borg pattern, but he told not why.

A real singleton in python has two advantages:

  1. you can subclass from it
  2. if you refactor your code and decide that you want different instances, the code change is minimized.
rocksportrocker
  • 7,251
  • 2
  • 31
  • 48