How to create a singleton in Python using a metaclass

In this tutorial, we will learn how to create a singleton in Python using a metaclass.

What is a singleton? 

Well, a singleton is a creational pattern that ensures that there can exist only one object of its kind. This way, it can only be accessed through a single point.

There are many ways to create a singleton i.e. decorators, base class, metaclasses, etc. We are going to see how we can create a singleton using a metaclass.

Create a singleton in Python using a metaclass

We can use a metaclass to create a singleton in Python. In the given example program we have created a metaclass with name SingletonMeta which overrides the __call__() method and manipulates it in such a way that there can never be more than one instance for a class that is an instance of this class. Then we create an instance of SingletonMeta class with the name Singleton as shown below in the code. The Singleton class is a singleton and there can never exist two different objects of this class. Hence its attributes and methods can only be accessed through a single point.

See the code for a better understanding.

class SingletonMeta(type):
  _instance = {}
  def __call__(cls, *args, **kwargs):
    if cls not in cls._instance:
      cls._instance[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
    return cls._instance[cls]
    
class Singleton(metaclass = SingletonMeta):
  pass

Now to check whether our code is right or not let’s try to create objects for this class and print them out. Here it is.

if __name__ == "__main__":
  singleton1 = Singleton()
  print(singleton1)
  
  singleton2 = Singleton()
  print(singleton2)

After executing the code we get something like this,

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

It’s very clear from the output that both the objects have the same instance. Which proves our code is right.

Thank you.

Also read:

Leave a Reply

Your email address will not be published. Required fields are marked *