Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton Pattern In Python

I am new to Python and I am trying to learn this language by checking and creating examples of design patterns in Python.

I have a confusion with classic implementation of Singleton Pattern. Most of the articles out there mentions following implementation of Singleton as classic

class Singleton(object):
    name = None

    @staticmethod
    def instance():
        if '_instance' not in Singleton.__dict__:
            Singleton._instance = Singleton()

        return Singleton._instance


s1 = Singleton().instance();
s2 = Singleton().instance();

assert s1 is s2

But I am not fully convinced with this implementation because no where we are restricting users from creating multiple objects of Singleton class and I can still create an instance of this class by calling Singleton(). In Java, we prevent this by making constructor of class as Private.

Another implementation someone pointed me out is

class Singleton(object):
    _instances = {}

    def __new__(class, *args, **kwargs):
        if class not in class._instances:
            instance = super().__new__(class)
            class.__instances[class] = instance
        return class._instances[class]

And this has spinned my head off. Can someone explain me how this works?

like image 404
Lokesh Agrawal Avatar asked Jun 15 '26 18:06

Lokesh Agrawal


1 Answers

The first thing to keep in mind is Python is not Java. It's not as restrictive as other languages. As Guido says, "we're all adults here". Nothing really prevents you from doing most things in Python. The solution is "don't do that".

However, there are several ways to do singletons. Another way, one that looks more "natural" to a user, is to use a factory function that looks like a class instantiation. Here's an example.

class _Singleton:
    _instance = None

    def hello(self):
        print("Hello!")


def Singleton():
    if _Singleton._instance is None:
        _Singleton._instance = _Singleton()
    return _Singleton._instance



s1 = Singleton()
s2 = Singleton()

assert s1 is s2
like image 90
Keith Avatar answered Jun 17 '26 09:06

Keith