Singleton in Python

This will be the easiest of all creational patterns. The concept is to create an instance of a class only once (regardless of how many times we call the class) and use that instance whenever we want. Let’s implement is fast on Python —


class SingletonMeta(type):

    _instance = None

    def __call__(self):
        if self._instance is None:
            self._instance = super().__call__()
        return self._instance


class Singleton(metaclass=SingletonMeta):
    # Now implement you singleton class
    def some_business_logic(self):
        pass


if __name__ == "__main__":

    s1 = Singleton()
    s2 = Singleton()

    # You can check they are both same instance
    assert(id(s1) == id(s2))

This is so easy! We made a metaclass SingletonMeta and then use that to build our class Singleton . Ok, now the question may arise “What is a metaclass?”. The answer is really simple, “Metaclasses are the ‘stuff’ that creates classes”. In Python, everything is an object, right? So metaclasses are the classes that are used to create these objects. Here is an elaborate answer about metaclass.

In our case, our SingletonMeta class is the creator of our Singleton class. And in this metaclass, we can define custom logic on how a class should behave or what it will be its property. In SingletonMeta class, we took an _instance and every time the class get __call__ to initiate itself, it tries to find the _instance , if not yet instantiated, creates the instance of the class and save it to _instance . So in the runtime, when it gets called again, it supplies the same instance.

Now the question may arise “Why would we need such a pattern?”. Well, the easiest example can be a REST/RPC client. In web applications, we need to call other services/API’s. So we make a client that normally does the communication and returns the result to us. This client can be used in several places in the same application, do we really need to make this same instance every time, to make a call? Here we can use the singleton. Also, the DB client, are we creating the client every time when we need some data from DB? Rather make a client when the application starts and use that connection to call DB. In case of concurrency, DB calls may use a connection pool to support parallel communication, but that’s a very different topic for now.

Hope this helps you. A clap will be much appreciated.