7

I have a singleton like this

class Singleton:

    class __impl:
        def __init__(self):
            print "INIT"

    __instance = None

    def __init__(self):
        # Check whether we already have an instance
        if Singleton.__instance is None:
            Singleton.__instance = Singleton.__impl()

        # Store instance reference as the only member in the handle
        self.__dict__['_Singleton__instance'] = Singleton.__instance

    def __getattr__(self, attr):
        """ Delegate access to implementation """
        return getattr(self.__instance, attr)

    def __setattr__(self, attr, value):
        """ Delegate access to implementation """
        return setattr(self.__instance, attr, value)

When I made several instances of Singleton I get two calls to init , I mean "INIT" is printed two times, and I supose that it shouldn't happened

Somebody has an idea of what is wrong with this or has a better way to implement this??

Steven Barragán
  • 1,015
  • 10
  • 18

4 Answers4

16

Here's a slightly simpler way to write a Singleton:

class Singleton(object):
    __instance = None
    def __new__(cls):
        if cls.__instance is None:
            cls.__instance = super(Singleton,cls).__new__(cls)
            cls.__instance.__initialized = False
        return cls.__instance

    def __init__(self):      
        if(self.__initialized): return
        self.__initialized = True
        print ("INIT")

a = Singleton()
b = Singleton()
print (a is b)

although there may be better ways. I have to admit that I've never been fond of singletons. I much prefer a factory type approach:

class Foo(object):
    pass

def foo_singleton_factory(_singlton = Foo()):
    return _singleton

a = foo_singleton_factory()
b = foo_singleton_factory()
print (a is b)

This has the advantage that you can keep getting the same instance of Foo if you want it, but you're not limited to a single instance if you decide 10 years down the road that you don't want a true singleton.

mgilson
  • 264,617
  • 51
  • 541
  • 636
  • here How come a and b are same? Isn't its going to give you different instances of singleton? – code muncher Apr 20 '16 at 19:14
  • 1
    @codemuncher -- in which version? In the first version, you see that on the first call, it sets `cls.__instance` and then keeps returning the same `cls.__instance` on subsequent calls. In the second version, it creates the singleton when the function is created and then keeps returning that value (unless you pass a different value for `_singleton`). – mgilson Apr 20 '16 at 19:19
  • second version, for my next call b = foo_singleton_factory(), isn't it gonna create another object, I'm confused . – code muncher Apr 21 '16 at 00:04
  • 3
    Nope, default arguments are only evaluated once -- when the function is created. They do not get re-evaluted for subsequent calls. This is the source of all sorts of confusion in python :-). See http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument for another case where it gets people. – mgilson Apr 21 '16 at 00:06
  • This does not work if you inherit the Singleton class – rajeshk Mar 01 '18 at 17:50
  • @mgilson It works perfectly but I'm confused in the first version. why doesn't it create a second instance? thanks – MohammadHossein Jamshidi May 09 '21 at 12:17
8

PEP 318 has an example of a singleton decorator for classes:

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

@singleton
class MyClass:
    ...

(though I haven't used it myself.)

Btw, about...

I made a singleton like this

Also, you should mention that you copied it directly from ActiveState.

aneroid
  • 11,031
  • 3
  • 33
  • 54
3

Since we're all ignoring your question and instead proposing alternative singleton implementations, I'll pitch in with my favourite. It takes advantage of the fact that a python module is only loaded once, no matter how many times you import it.

It's also based on the python motto "we're all consenting adults here" since, if you REALLY want to, you can instantiate it multiple times... but then you really have to put in an extra effort to do it wrong.

So in mysingleton.py:

class SingletonClass(object):
    def __init__(self):
        # There's absolutely nothing special about this class
        # Nothing to see here, move along
        pass

# Defying PEP8 by capitalizing name
# This is to point out that this instance is a Singleton
Singleton = SingletonClass()

# Make it a little bit harder to use this module the wrong way
del SingletonClass

Then use it like this:

from mysingleton import Singleton

# Use it!

I said you had to put in an extra effort to do things wrong. Here's how you could create two instances of the singleton class, making it a singleton no more:

another_instance = Singleton.__class__()

So how do you avoid this problem? I'll quote the doctor: don't do that then!


NOTE: This was added after the comments below were made

While I'm at it, here's another singleton variant that minimizes the amount of complicated code. It uses metaclasses:

class SingletonMeta(type):
    # All singleton methods go in the metaclass
    def a_method(cls):
        return cls.attribute

    # Special methods work too!
    def __contains__(cls, item):
        return item in cls.a_list

class Singleton(object):
    __metaclass__ = SingletonMeta
    attribute = "All attributes are class attributes"

    # Just put initialization code directly into the class
    a_list = []
    for i in range(0, 100, 3):
        a_list.append(i)

print Singleton.a_method()
print 3 in Singleton

In python 3 you'd create the singleton instance like this instead:

class Singleton(metaclass=SingletonMeta):
    attribute = "One... two... five!"

Now this one is a little more iffy, since the singleton is a class, and you can make instances of the singleton. In theory this is OK, since the singleton will still be a singleton even if it has instances, but you need to remember that Singleton() is not the singleton -- Singleton is! It might even suit your needs to have the singleton attributes readily available to its instances as class attributes.

Lauritz V. Thaulow
  • 41,893
  • 11
  • 64
  • 87
  • I like this one. The only thing I don't like is that you really have an instance and you can't customize the instances creation at all. e.g. you can't do `Singleton('foo','bar','baz')` (Unless you provide `__call__`, but then you can't use `__call__` for other purposes ...) – mgilson Sep 06 '12 at 17:51
  • This is good advice. The easiest way to create a singleton is to just instantiate the class once! – matt b Sep 06 '12 at 17:59
  • Nice one, real singleton. Oddly, it can still be sub-classed after deletion using `class AnotherClass(Singleton.__class__): pass` and a function ("method") defined in `SingletonClass` like `def boo(self): print 'boo!'` still works on an instance of `AnotherClass`. Along those lines, **`b = Singleton.__class__()` also works...** `isinstance(b, Singleton.__class__)` (obviously?) gives `True`. – aneroid Sep 06 '12 at 18:52
  • ...(contd. from `b = Singleton.__class__()`): `b is Singleton` is `False` – aneroid Sep 06 '12 at 18:59
1

An other way:

>>> class Singleton(object):
...     def __new__(cls, *args, **kwargs):
...             try:
...                     return cls._instance
...             except AttributeError:
...                     val = cls._instance = object.__new__(cls, *args, **kwargs)
...                     return val
... 
>>> class A(Singleton): pass
... 
>>> a = A()
>>> a2 = A()
>>> a2 is a
True
>>> class B(Singleton): pass
... 
>>> b = B()
>>> b2 = B()
>>> b2 is b
True
>>> b is a
False
>>> class D(Singleton):
...     def __init__(self, v): self.v = v
... 
>>> d = D(1)
>>> d.v
1

If you are worried about multiple calls to __init__ then the choice is between using a decorator or a metaclass.

Overriding the __new__ method allow multiple __init__ calls because python always calls the __init__ method of an object returned by __new__ if the value returned is an instance of that class.

Anyway I think using a decorator it's the best thing, because it's probably the simpler solution.

If you want to know more ways of creating a singleton in python read this question.

By the way, if you want to have all instances with the same state(and not identity) then you might be interested in the Borg pattern. If you are unsure which one to choose, see this answer.

Community
  • 1
  • 1
Bakuriu
  • 85,459
  • 18
  • 168
  • 202
  • I'm not super familiar with all the magic that goes into `__new__` and how to use it effectively, but my impression is that this will still call `__init__` multiple times on the same instance (which is what I think OP was trying to avoid) – mgilson Sep 06 '12 at 17:46
  • Yes @mgilson you are correct. I've often used this method because I did not care much about multiple init calls. I've added a brief explanation about why this methods does multiple init calls. – Bakuriu Sep 06 '12 at 18:24