CaseyJones
CaseyJones

Reputation: 505

Why does my singleton implementation not work in Python?

The below is an attempt to implement Singleton in python 3 but it doesn't appear to work. When I instantiate, the _instance is always None and both instances (a and b) have different addresses in memory - why?

class Singleton(object):
    _instance = None

    def __call__(self, *args, **kwargs):
        if self._instance is None:
            self._instance = super().__call__(*args, **kwargs)
        return self._instance

    def __init__(self, *args, **kwargs):
        print(self._instance, self)


a = Singleton()
b = Singleton()

The output is:

(None, <__main__.Singleton object at 0x7f382956c190>)
(None, <__main__.Singleton object at 0x7f382956c410>)

Upvotes: 0

Views: 48

Answers (1)

jferard
jferard

Reputation: 8180

The __call__ method is not what you think it is. It is meant to make instances of classes callable like functions:

class A:
    def __call__(self):
        print("called")

a = A() # prints nothing
a() # prints "called"

What you are looking for is the __new__ method:

Called to create a new instance of class cls.

You can write the singleton like this (very similar to what you wrote):

class Singleton(object):
    _instance = None

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

    def __init__(self, *args, **kwargs):
        print(self._instance, self)


a = Singleton()
b = Singleton()

The output is now:

<__main__.Singleton object at 0x7f149bf3cc88> <__main__.Singleton object at 0x7f149bf3cc88>
<__main__.Singleton object at 0x7f149bf3cc88> <__main__.Singleton object at 0x7f149bf3cc88>

Upvotes: 1

Related Questions