476

There seem to be many ways to define singletons in Python. Is there a consensus opinion on Stack Overflow?

martineau
  • 99,260
  • 22
  • 139
  • 249
Jamie
  • 7,022
  • 4
  • 19
  • 15
  • 7
    [Singletons are Pathological Liars](http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/), are they not? – Jonas Byström Jul 05 '12 at 15:01
  • 15
    "this question is not a good fit for our Q&A format" - I think this is not a subjective question, is there a way in which to ask such questions such that it fits the SO Q&A format ? – binithb Sep 13 '14 at 22:13
  • 13
    I don't agree that this is not constructive. Could it be re-opened if moved to http://programmers.stackexchange.com ? – gogo_gorilla Aug 06 '15 at 09:35
  • 1
    @stackoverflowwww no because it's opinion-based and progs.SE doesn't like that. – ratchet freak Aug 06 '15 at 09:44
  • 1
    @ratchetfreak What makes the question popular is that people like me are looking for different ways to create Singletons in python. There are alternatives with pros and cons or which may be suitable only in certain situations. The question could be re-formulated a la "What different ways exist in Python to create a singleton? I am especially interested in the difference between solutions which are based on a class and those based on a class instance." – gogo_gorilla Aug 06 '15 at 09:49
  • 1
    @stackoverflowwww this would be a poor fit for Programmers - it would be quickly voted down and closed over there, see [What is the problem with “Pros and Cons”?](http://meta.programmers.stackexchange.com/q/6758/31260) Recommended reading: **[What goes on Programmers.SE? A guide for Stack Overflow](http://meta.programmers.stackexchange.com/q/7182/31260)** – gnat Aug 06 '15 at 14:05
  • 1
    @gnat I see. So one should either present a solution for a Singleton and ask for a review, or, ask more specifically, e.g. "how can I create a Singleton in Python using a class?". Am I on the right track? – gogo_gorilla Aug 06 '15 at 14:16
  • @stackoverflowwww something like that might work. Another thing worth keeping in mind, Programmers tend to expect a [solid research effort](http://meta.programmers.stackexchange.com/questions/6559/why-is-research-important). Skip that, and you risk having a question stay open, but voted down. Or closed as a dupe (per my recollection, there is already lots of questions in _singleton_ tag over there) – gnat Aug 06 '15 at 14:46
  • @JonasByström they are if your language is too limited to implicitly initialize them. in python it’s very much possible to keep the promise that “whenever i want to access this, it will be initialized”, e.g. (stupid idea) by making every field a property doing “initialize if not initialized”. but the other problems weigh more and you should instead use context managers or something. – flying sheep Oct 01 '15 at 09:36
  • @flyingsheep: did you check the link at all (you big-S'ed Singleton!)? – Jonas Byström Oct 01 '15 at 10:46
  • Related: [Creating a singleton in Python](//stackoverflow.com/q/6760685) – Aran-Fey May 28 '18 at 13:07

21 Answers21

379

I don't really see the need, as a module with functions (and not a class) would serve well as a singleton. All its variables would be bound to the module, which could not be instantiated repeatedly anyway.

If you do wish to use a class, there is no way of creating private classes or private constructors in Python, so you can't protect against multiple instantiations, other than just via convention in use of your API. I would still just put methods in a module, and consider the module as the singleton.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Staale
  • 24,584
  • 22
  • 63
  • 85
  • 12
    Couldn't the constructor just check if an instance has already been created and throw an exception if it has been? – Casebash May 16 '10 at 07:56
  • 47
    This is fine so long as you don't need to use inheritance as part of your design, in which case most of the answers below are more suitable – Jim Jeffries Jun 06 '11 at 08:23
  • 1
    For accessing "module properties" the right way, see: http://stackoverflow.com/questions/6841853/python-accessing-module-scope-vars/6842257#6842257 – Frosty Z Jul 27 '11 at 10:22
  • Does that means singleton classes are not possible in python at all ? – Yugal Jindle Nov 22 '11 at 05:21
  • There is the use of a singleton class decorator which would serve the purpose of the singleton design pattern. It's documented on the PEP 318 page http://www.python.org/dev/peps/pep-0318/ – James Hurford Feb 09 '12 at 04:34
  • 11
    It's broken when you have cyclic import – dieend Sep 25 '12 at 10:49
  • 15
    what will i do if i want that module to be inheritable ? – yossi Nov 26 '12 at 09:09
  • Opposing inheritance to the solution from Staale is nonsensical. It is possible to inherit from functions in Python, since functions are classes, just as modules themselves are. Example: http://pythonfiddle.com/function-inheritance – Christophe Apr 11 '15 at 13:38
  • 11
    This is false in my opinion. One annoyance about module level interfaces is managing the imports. For example, Python `logging` is a module level interface. In order to ensure you fully clean up after `logging` you must call `logging.shutdown()`. This means you must import `logging` into the module which calls `shutdown`. If it was a singleton pattern it is possible to call shutdown on the instance in any module to which it is passed. – Matt Feb 25 '16 at 06:49
  • This isn't an answer to the question. Please keep this sort of reply to comments. – Shayne Oct 21 '17 at 08:10
  • It's also a problem when you want to avoid the function to reaload a large amount of data each time it's called – Nickpick Nov 10 '17 at 13:34
  • 1
    @Matt You could just pass the `logging` module, then call `whatever_i_got_logging_as.shutdown()`. Or you could get passed `logging.shutdown` and then just run `whatever_i_got_shutdown_as()`. – wizzwizz4 Apr 21 '18 at 18:25
  • The need can come from allowing better logging printing the class name in any of your statements which can give further context to your logging. `timestamp [MyClass] Something happened` – rodi Jul 05 '18 at 19:22
  • 1
    Having tried to implement a singleton with a module. I have found this simply does not work. There are many ways that the module can be imported twice, causing it to lose state. – Duane Dec 25 '18 at 00:51
  • @Duane: When a module is `import`ed for the first time, it is cached in `sys.modules` and if it's ever imported again the cached copy is returned instead of the code in it being executed again, so the current state is not disturbed—so part of what you say is mistaken. The effects of this why modules are said to effectively be singletons. – martineau Jan 05 '19 at 09:33
  • @Duane: I found a good explanation of how modules work in this regard in a section titled [How do I share global variables across modules?](https://docs.python.org/3/faq/programming.html#how-do-i-share-global-variables-across-modules) in Python's online documentation (within its [Programming FAQ](https://docs.python.org/3/faq/programming.html#programming-faq)). – martineau Jan 05 '19 at 10:30
  • 2
    @martineau Unfortunately that is all true only in theory. There are loopholes that allow modules to be imported twice. For example, if the module appears twice in the pythonpath under different namespaces, it can be imported twice, because the module caching system cannot tell its the same file.https://stackoverflow.com/questions/4798589/what-could-cause-a-python-module-to-be-imported-twice – Duane Jan 06 '19 at 18:41
  • 1
    If this was a proper solution, the singleton pattern wouldn't exist to begin with. In languages like Java you'd just use a static class. But that's not the case. – Noctiphobia Jan 19 '20 at 05:01
  • I started from modules but then I have to import say 20 functions from each module. It does not look very aesticallly pleasing. So I created a class in a module and a single instance of this class in the same module (I suppose it is called the global class pattern). I import just this instance and save big on typing. And I do not care that it is possible to create multiple instances of the same class in other modules. My coworker tells me that I have to use class methods in this class instead, should I do it? – zzz777 Mar 19 '21 at 22:45
320

Here's my own implementation of singletons. All you have to do is decorate the class; to get the singleton, you then have to use the Instance method. Here's an example:

@Singleton
class Foo:
   def __init__(self):
       print 'Foo created'

f = Foo() # Error, this isn't how you get the instance of a singleton

f = Foo.instance() # Good. Being explicit is in line with the Python Zen
g = Foo.instance() # Returns already created instance

print f is g # True

And here's the code:

class Singleton:
    """
    A non-thread-safe helper class to ease implementing singletons.
    This should be used as a decorator -- not a metaclass -- to the
    class that should be a singleton.

    The decorated class can define one `__init__` function that
    takes only the `self` argument. Also, the decorated class cannot be
    inherited from. Other than that, there are no restrictions that apply
    to the decorated class.

    To get the singleton instance, use the `instance` method. Trying
    to use `__call__` will result in a `TypeError` being raised.

    """

    def __init__(self, decorated):
        self._decorated = decorated

    def instance(self):
        """
        Returns the singleton instance. Upon its first call, it creates a
        new instance of the decorated class and calls its `__init__` method.
        On all subsequent calls, the already created instance is returned.

        """
        try:
            return self._instance
        except AttributeError:
            self._instance = self._decorated()
            return self._instance

    def __call__(self):
        raise TypeError('Singletons must be accessed through `instance()`.')

    def __instancecheck__(self, inst):
        return isinstance(inst, self._decorated)
Paul Manta
  • 27,853
  • 27
  • 109
  • 192
  • 23
    Python being battery-included this should be part of a `desing_pattern` standard library, thanks – dashesy Aug 31 '14 at 00:23
  • I am new to python. If I decorate my base class with @Singleton, would the child classes becomes one too? – Ege Aydın Mar 18 '17 at 21:22
  • @EgeAydın You're not going to be able to inherit from a class decorated with `@Singleton`, so there aren't going to be any child classes. This is a technical limitation, it's not by design. – Paul Manta Mar 18 '17 at 22:12
  • 2
    This decorator does not support constructors with arguments. For a more general purpose decorator, use: `def Instance(self, *args, **kwargs): self._instance = self._decorated(*args, **kwargs)` – akhan Apr 28 '17 at 05:16
  • 11
    @akhan I decided not to support constructors with arguments on purpose, because the arguments would only be used the first time and ignored all of the other times. This can make your code very hard to follow, since you might use different arguments in different places, but you might not know which one of these calls is the one that actually initializes the singleton. – Paul Manta Apr 28 '17 at 07:53
  • 6
    @akhan If you really want to initialize your singleton with arguments, you should have a separate `initialize()` method that can take any arguments and throws if called more than once. – Paul Manta Apr 28 '17 at 07:54
  • Thank you! Any ideas how to make pylint not complain about it? (preferably without disabling anything). I'm getting `Class MyClass has no 'Instance' member` error. – Dennis Golomazov Jul 19 '17 at 21:32
  • @DennisGolomazov Your capitalisation is wrong. – wizzwizz4 Apr 21 '18 at 18:27
  • @PaulManta You can use `type(Foo.instance())()` to create a new one, by the way. – wizzwizz4 Apr 21 '18 at 18:28
  • 1
    @wizzwizz4 Ah, good point, but at that point you're just asking for trouble. The goal is to prevent you from creating more instances by mistake, not to prevent you from hacking it. – Paul Manta Apr 21 '18 at 20:38
  • @PaulManta `NoneType` is a true singleton in this respect. (Just pointing out that there's a way to do it with no flaws that's supported by Python; you're right about that not being a problem.) – wizzwizz4 Apr 21 '18 at 20:40
  • 23
    This is a ***really bad*** singleton implementation. First of all, it's not a proper decorator because it doesn't use [`functools.wraps`](https://docs.python.org/3/library/functools.html#functools.wraps) or [`functools.update_wrapper`](https://docs.python.org/3/library/functools.html#functools.update_wrapper). Secondly, having to get the instance by calling `Foo.Instance()` is horribly unpythonic and there's exactly 0 reasons why it couldn't have been implemented as `Foo()` instead. Thirdly, replacing the class like that produces unexpected results like `type(Foo.instance()) is Foo` -> `False` – Aran-Fey May 28 '18 at 12:59
  • 1
    Fair, I can agree that something like `Foo.get_instance()` is more self-documenting than just `Foo()`. But the other two things I said still hold true, and it's still a **really bad** implementation. – Aran-Fey Jul 25 '18 at 20:35
  • 4
    @Aran-Fey seems like this solution really bursts your bubble lol. I don't believe Paul Manta ever said this is the best solution world wide. He was just trying to answer the original authors question. I think it's a great solution to a 'lack thereof' in python. – JokerMartini Jul 05 '19 at 15:17
197

You can override the __new__ method like this:

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(
                                cls, *args, **kwargs)
        return cls._instance


if __name__ == '__main__':
    s1 = Singleton()
    s2 = Singleton()
    if (id(s1) == id(s2)):
        print "Same"
    else:
        print "Different"
proski
  • 2,903
  • 23
  • 25
jojo
  • 3,336
  • 1
  • 22
  • 21
  • 61
    WARNING: If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__(). If any subclass of Singleton implements __init__(), it will be called multiple times with the same self. I ended up using a factory instead. – alsuren Sep 08 '11 at 12:48
  • 7
    this would be better using a metaclass as the answer here: http://stackoverflow.com/a/33201/804147 – underrun Jan 23 '12 at 15:24
  • 2
    This gives the following warning - `singleton.py:9: DeprecationWarning: object.__new__() takes no parameters` `cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)` – Siddhant Jan 02 '13 at 16:17
  • 2
    @Siddhant: worse yet, in Python 3, that warning becomes an error. See http://bugs.python.org/issue1683368 and http://blog.jaraco.com/2014/05/how-to-safely-override-init-or-new-in.html for more details. – Jason R. Coombs Jun 14 '14 at 16:36
120

A slightly different approach to implement the singleton in Python is the borg pattern by Alex Martelli (Google employee and Python genius).

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

So instead of forcing all instances to have the same identity, they share state.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Peter Hoffmann
  • 48,060
  • 14
  • 71
  • 58
86

The module approach works well. If I absolutely need a singleton I prefer the Metaclass approach.

class Singleton(type):
    def __init__(cls, name, bases, dict):
        super(Singleton, cls).__init__(name, bases, dict)
        cls.instance = None 

    def __call__(cls,*args,**kw):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args, **kw)
        return cls.instance

class MyClass(object):
    __metaclass__ = Singleton
unutbu
  • 711,858
  • 148
  • 1,594
  • 1,547
Acuminate
  • 1,206
  • 7
  • 4
  • 2
    This pattern is against the "Single Responsibility Principle" (http://c2.com/cgi/wiki?SingleResponsibilityPrinciple). See point (2) in http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx. – haridsv May 20 '10 at 19:21
  • 18
    @haridsv I don't agree. The fact that the class is a singleton __is__ abstracted away in the metaclass implementation -- the class itself doesn't know or care that it's a singleton as it's not in charge of enforcing that requirement, the metaclass is. The method below is clearly a violation, however, as you note. The base class method is somewhere in between. – agf Jul 23 '11 at 04:38
  • 1
    the problem with this one is that you can create multiple instances of `MyClass` through `deepcopy`. If you run `from copy import deepcopy as dcp ; m1 = MyClass() ; m2 = dcp(m1) ; print m1 is m2`, you'll get `False`. Do you know any way around it? –  Mar 27 '12 at 09:29
  • 1
    @dare2be: Couldn't the copying issue you mention be addressed simply by having the metaclass also add a `__deepcopy__()` method to the class created? – martineau Dec 03 '12 at 18:18
  • @Acuminate: Shouldn't the metaclass override the `__new__()` method instead of `__init__()` to make it actually return the same object each time? – martineau Dec 03 '12 at 18:27
  • 3
    @martineau: That's `type.__init__` it's overriding, not `MyClass.__init__` – Eric Feb 03 '14 at 00:00
  • what if MyClass inherits from another class? How can I avoid "metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases" – Nickpick Oct 26 '17 at 14:21
  • 2
    Another stackoverflow comment mentioned that you can fix this bug by overriding __new__() ``` class SingletonMeta(type): def __new__(cls, name, bases, dict): dict['__deepcopy__'] = dict['__copy__'] = lambda self, *args: self return super(SingletonMeta, cls).__new__(cls, name, bases, dict) ``` - https://stackoverflow.com/a/9887928/748503 – James McGuigan Nov 24 '17 at 18:38
46

See this implementation from PEP318, implementing the singleton pattern with a decorator:

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    ...
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Wei
  • 485
  • 4
  • 2
  • 24
    The problem with this decorator is that 'MyClass' is not a class anymore, e.g. super() won't work, classmethods won't work etc: @singleton class MyClass(BaseClass): def __init__(self): super(MyClass, self).__init__() – mkm Oct 28 '11 at 09:40
  • 1
    It seems that the decorator should apply to the __new__ method, rather than the class, to deal with the inheritance issue. At which point, the elegant readability of the decorator is diminished. Or the decorator needs to fritz with the class it is decorating to make the __new__ function do something sensible. – F1Rumors Jun 29 '16 at 17:01
29

The Python documentation does cover this:

class Singleton(object):
    def __new__(cls, *args, **kwds):
        it = cls.__dict__.get("__it__")
        if it is not None:
            return it
        cls.__it__ = it = object.__new__(cls)
        it.init(*args, **kwds)
        return it
    def init(self, *args, **kwds):
        pass

I would probably rewrite it to look more like this:

class Singleton(object):
    """Use to create a singleton"""
    def __new__(cls, *args, **kwds):
        """
        >>> s = Singleton()
        >>> p = Singleton()
        >>> id(s) == id(p)
        True
        """
        self = "__self__"
        if not hasattr(cls, self):
            instance = object.__new__(cls)
            instance.init(*args, **kwds)
            setattr(cls, self, instance)
        return getattr(cls, self)

    def init(self, *args, **kwds):
        pass

It should be relatively clean to extend this:

class Bus(Singleton):
    def init(self, label=None, *args, **kwds):
        self.label = label
        self.channels = [Channel("system"), Channel("app")]
        ...
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Brian Bruggeman
  • 4,098
  • 2
  • 27
  • 44
  • 6
    +1 for being the only one mentioning Guido van Rossum’s implementation. However your own version is wrong: you should not use `hasattr` and `getattr` inside `__new__` as they both call `object.__getattribute__` which in turn looks up your `"__self__"` attribute through all the class hierarchy instead of only the current class. If Guido uses `__dict__` for attribute access that is for a reason. Try: `class A(GuidoSingleton): pass`, `class B(A): pass`, `class C(YourSingleton): pass`, `class D(C): pass`, `print(A(), B(), C(), D())`. All subclasses refer to the same instance with `YourSingleton`! – Maggyero Dec 15 '17 at 16:56
  • 2
    +1 for reminding us that Python documentation is always the best place to start our search for singleton and other design patterns. – user-asterix Nov 13 '18 at 00:58
27

As the accepted answer says, the most idiomatic way is to just use a module.

With that in mind, here's a proof of concept:

def singleton(cls):
    obj = cls()
    # Always return the same object
    cls.__new__ = staticmethod(lambda cls: obj)
    # Disable __init__
    try:
        del cls.__init__
    except AttributeError:
        pass
    return cls

See the Python data model for more details on __new__.

Example:

@singleton
class Duck(object):
    pass

if Duck() is Duck():
    print "It works!"
else:
    print "It doesn't work!"

Notes:

  1. You have to use new-style classes (derive from object) for this.

  2. The singleton is initialized when it is defined, rather than the first time it's used.

  3. This is just a toy example. I've never actually used this in production code, and don't plan to.

Community
  • 1
  • 1
Lambda Fairy
  • 11,500
  • 5
  • 37
  • 56
  • I tried this but got the error: TypeError: unbound method () must be called with Integer instance as first argument (got type instance instead) My Integer class is your Duck class: @singleton class Integer(object): """ Class for objects of integer type """ pass – Tom Prats Mar 11 '13 at 07:03
  • Thanks for pointing that out. I have no idea why that happens, but the edited version should work on Python 2.7 and 3.3. – Lambda Fairy Mar 12 '13 at 08:02
  • This is not good, the ``__init__()`` method is being called when the class is defined (while you may want to wait until the first time it's used), and afterwards at every call of ``Duck()``. – tiho Apr 10 '13 at 17:46
  • 2
    I've documented the first issue, and fixed the second. Thanks for pointing it out. – Lambda Fairy Apr 13 '13 at 07:54
25

I'm very unsure about this, but my project uses 'convention singletons' (not enforced singletons), that is, if I have a class called DataController, I define this in the same module:

_data_controller = None
def GetDataController():
    global _data_controller
    if _data_controller is None:
        _data_controller = DataController()
    return _data_controller

It is not elegant, since it's a full six lines. But all my singletons use this pattern, and it's at least very explicit (which is pythonic).

ndmeiri
  • 4,728
  • 12
  • 32
  • 41
u0b34a0f6ae
  • 42,509
  • 13
  • 86
  • 97
  • +1 In Python should everything be about conventions (because you can usually hack around enforced boundaries). Personally, I prefer a classmethod and class variable to access and store the instance, so you don't have to use `global`. (I generally discourage the usage of `global` though this is one of a few use cases where it is acceptable.) – schlamar Jan 11 '13 at 10:23
  • should `DataController` be `_DataController`? Otherwise one can instance it directly – nos Nov 13 '20 at 20:19
  • This is the best solution in my opinion, because it is the simplest to understand when you come across the code in the future. – joanis Apr 08 '21 at 17:59
17

The one time I wrote a singleton in Python I used a class where all the member functions had the classmethod decorator.

class Foo:
    x = 1
  
    @classmethod
    def increment(cls, y=1):
        cls.x += y
Maggyero
  • 3,120
  • 2
  • 24
  • 43
David Locke
  • 16,816
  • 8
  • 30
  • 53
  • I like this approach, but there is a minor gotcha. At least with Python 2.6, you can't make methods like `__len__` or `__getitem__` work as classmethods, so you don't have as much flexibility to customize as you would with an object. Since I often want to use a Singleton as a collection of data, that's a bit disappointing. – Dan Homerick Jul 29 '10 at 23:19
  • Seems to me that this is nothing more than the wrapping of a bunch stuff into a namespace...not that there's anything wrong with that, some have even said they think they're a honking great idea (`import this`) -- it's just that this approach is not much more than simple that and seems awfully close to using global variables which is generally considered a bad engineering practice. – martineau Dec 10 '12 at 03:42
  • 2
    @martineau I suggest that using a singleton is awfully close to using global variables no matter how it is implemented. – David Locke Dec 12 '12 at 16:11
  • 2
    Singletons are better than global variables in two ways: They don't pollute the global namespace at all (or as much, like your answer), and that they also provide lazy evaluation, whereas global variables generally do not (and neither does your answer). – martineau Dec 12 '12 at 21:30
  • 1
    @DanHomerick for `__len__`, `__getitem__` and even `@property` you can use `__metaclass__` set to a class defining the above. Work great. I vote for a class as a singleton, which it is by the design of the language, being an instance of it's metaclass. Actually, all methods may be defined in the metaclass and then the class will be used just as a reference to the singleton – Leonid Usov Aug 05 '15 at 17:47
11

Creating a singleton decorator (aka an annotation) is an elegant way if you want to decorate (annotate) classes going forward. Then you just put @singleton before your class definition.

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    ...
Matt Alcock
  • 10,631
  • 13
  • 41
  • 59
  • I wonder why was this not up-voted ? Great.. please explain why and how is `getinstance` method getting called ? – Yugal Jindle Mar 10 '12 at 11:43
  • 3
    Seems like you have copied PEP318 ? – Yugal Jindle Mar 10 '12 at 11:53
  • @YugalJindle: FYI, in a nutshell the class decorator function here replaces the class object that has been passed to it with a function which returns either a new instance of the class it creates by calling it when it's the first time one is being created, or a copy of that first one if it's not the first time. – martineau Dec 12 '12 at 20:22
  • 6
    One potential -- although likely minor -- problem with this approach is that the class name will end up being bound to a function, not a class object. Which means it won't be possible to create a subclass of `MyClass` using a normal `class Derived(MyClass)` statement. – martineau Dec 12 '12 at 20:36
  • I'd say that the problem raised by @martineau is a major one with this approach, since the whole point of using a class and not a module is to be able to create subclasses. – tiho Apr 10 '13 at 17:42
  • 3
    @tiho: I don't agree that it's a major issue for several reasons. Some being: It's easy to fix/workaround in at least a couple of ways, and I think the main reason to create classes is encapsulation, not to allow or support inheritance, something which is especially true wrt singleton classes. – martineau Apr 10 '13 at 20:06
  • -1, this solution is a duplicate of prior one posted in 08 by @lambda-fairy, making the effort to post should have made the next answer a delta, if there is anything to add to the prior post! Not sure I see the delta and Im disinclined to check – msudder Jul 03 '16 at 15:40
8

There are also some interesting articles on the Google Testing blog, discussing why singleton are/may be bad and are an anti-pattern:

kͩeͣmͮpͥ ͩ
  • 7,577
  • 24
  • 38
FrankS
  • 2,254
  • 3
  • 26
  • 32
7

I think that forcing a class or an instance to be a singleton is overkill. Personally, I like to define a normal instantiable class, a semi-private reference, and a simple factory function.

class NothingSpecial:
    pass

_the_one_and_only = None

def TheOneAndOnly():
    global _the_one_and_only
    if not _the_one_and_only:
        _the_one_and_only = NothingSpecial()
    return _the_one_and_only

Or if there is no issue with instantiating when the module is first imported:

class NothingSpecial:
    pass

THE_ONE_AND_ONLY = NothingSpecial()

That way you can write tests against fresh instances without side effects, and there is no need for sprinkling the module with global statements, and if needed you can derive variants in the future.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Mark Evans
  • 473
  • 4
  • 6
  • I think it is worse than overkill. Forcing an implicit behavior is just not pythonic. And I have more comments on the duplicate answer :-) http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python#comment19819697_1314783 – schlamar Jan 11 '13 at 10:29
3
class Singleton(object[,...]):

    staticVar1 = None
    staticVar2 = None

    def __init__(self):
        if self.__class__.staticVar1==None :
            # create class instance variable for instantiation of class
            # assign class instance variable values to class static variables
        else:
            # assign class static variable values to class instance variables
John Mee
  • 44,003
  • 31
  • 133
  • 171
3

The Singleton Pattern implemented with Python courtesy of ActiveState.

It looks like the trick is to put the class that's supposed to only have one instance inside of another class.

Mark Biek
  • 135,050
  • 52
  • 150
  • 195
3

OK, singleton could be good or evil, I know. This is my implementation, and I simply extend a classic approach to introduce a cache inside and produce many instances of a different type or, many instances of same type, but with different arguments.

I called it Singleton_group, because it groups similar instances together and prevent that an object of the same class, with same arguments, could be created:

# Peppelinux's cached singleton
class Singleton_group(object):
    __instances_args_dict = {}
    def __new__(cls, *args, **kwargs):
        if not cls.__instances_args_dict.get((cls.__name__, args, str(kwargs))):
            cls.__instances_args_dict[(cls.__name__, args, str(kwargs))] = super(Singleton_group, cls).__new__(cls, *args, **kwargs)
        return cls.__instances_args_dict.get((cls.__name__, args, str(kwargs)))


# It's a dummy real world use example:
class test(Singleton_group):
    def __init__(self, salute):
        self.salute = salute

a = test('bye')
b = test('hi')
c = test('bye')
d = test('hi')
e = test('goodbye')
f = test('goodbye')

id(a)
3070148780L

id(b)
3070148908L

id(c)
3070148780L

b == d
True


b._Singleton_group__instances_args_dict

{('test', ('bye',), '{}'): <__main__.test object at 0xb6fec0ac>,
 ('test', ('goodbye',), '{}'): <__main__.test object at 0xb6fec32c>,
 ('test', ('hi',), '{}'): <__main__.test object at 0xb6fec12c>}

Every object carries the singleton cache... This could be evil, but it works great for some :)

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Mychot sad
  • 360
  • 4
  • 8
2

Singleton's half brother

I completely agree with staale and I leave here a sample of creating a singleton half brother:

class void:pass
a = void();
a.__class__ = Singleton

a will report now as being of the same class as singleton even if it does not look like it. So singletons using complicated classes end up depending on we don't mess much with them.

Being so, we can have the same effect and use simpler things like a variable or a module. Still, if we want use classes for clarity and because in Python a class is an object, so we already have the object (not and instance, but it will do just like).

class Singleton:
    def __new__(cls): raise AssertionError # Singletons can't have instances

There we have a nice assertion error if we try to create an instance, and we can store on derivations static members and make changes to them at runtime (I love Python). This object is as good as other about half brothers (you still can create them if you wish), however it will tend to run faster due to simplicity.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
neu-rah
  • 1,641
  • 18
  • 31
2

Being relatively new to Python I'm not sure what the most common idiom is, but the simplest thing I can think of is just using a module instead of a class. What would have been instance methods on your class become just functions in the module and any data just becomes variables in the module instead of members of the class. I suspect this is the pythonic approach to solving the type of problem that people use singletons for.

If you really want a singleton class, there's a reasonable implementation described on the first hit on Google for "Python singleton", specifically:

class Singleton:
    __single = None
    def __init__( self ):
        if Singleton.__single:
            raise Singleton.__single
        Singleton.__single = self

That seems to do the trick.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
John
  • 13,312
  • 12
  • 54
  • 54
2

My simple solution which is based on the default value of function parameters.

def getSystemContext(contextObjList=[]):
    if len( contextObjList ) == 0:
        contextObjList.append( Context() )
        pass
    return contextObjList[0]

class Context(object):
    # Anything you want here
Tiezhen
  • 83
  • 6
1
class Singeltone(type):
    instances = dict()

    def __call__(cls, *args, **kwargs):
        if cls.__name__ not in Singeltone.instances:            
            Singeltone.instances[cls.__name__] = type.__call__(cls, *args, **kwargs)
        return Singeltone.instances[cls.__name__]


class Test(object):
    __metaclass__ = Singeltone


inst0 = Test()
inst1 = Test()
print(id(inst1) == id(inst0))
0

In cases where you don't want the metaclass-based solution above, and you don't like the simple function decorator-based approach (e.g. because in that case static methods on the singleton class won't work), this compromise works:

class singleton(object):
  """Singleton decorator."""

  def __init__(self, cls):
      self.__dict__['cls'] = cls

  instances = {}

  def __call__(self):
      if self.cls not in self.instances:
          self.instances[self.cls] = self.cls()
      return self.instances[self.cls]

  def __getattr__(self, attr):
      return getattr(self.__dict__['cls'], attr)

  def __setattr__(self, attr, value):
      return setattr(self.__dict__['cls'], attr, value)
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
mkm
  • 1,325
  • 1
  • 13
  • 21