Singleton Design Pattern in Python

Singleton Design Pattern in Python

  1. Use the Decorators to Implement the Singleton Design Pattern in Python
  2. Use a Base Class to Implement the Singleton Design Pattern in Python
  3. Use a Metaclass to Implement the Singleton Design Pattern in Python
  4. Use a Module to Implement the Singleton Design Pattern in Python

Design patterns can represent some code to solve a problem. Singleton is one such design pattern, and we can create different objects of a class in Python.

This pattern restricts only one object of a given class. There are several methods to simulate this pattern in Python.

Use the Decorators to Implement the Singleton Design Pattern in Python

Decorators in Python are functions that can take other functions and objects as arguments and modify their behavior. To use decorators, we use the @ sign.

We can use them to implement the Singleton design pattern.

See the following example,

def singleton_dec(class_):
    instances = {}
    def getinstance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]
    return getinstance

@singleton_dec
class Sample():
    def __init__(self):
        print("Object created.")

x = Sample();
y = Sample();
print(x,y)

Output:

Object created.
<__main__.Sample object at 0x0000015E72D3CA48> <__main__.Sample object at 0x0000015E72D3CA48>

In the above example, we created a decorator that takes the whole class as an argument. This decorator allows us to implement Singleton objects, which can be confirmed by the location of x and y.

The downside of using decorators for Singleton is that the final class Sample becomes a function, so we cannot use class methods.

Use a Base Class to Implement the Singleton Design Pattern in Python

A base class is a special class from which we derive other classes. No instances of this base class are created.

We can use a base class to provide the structure for Singleton in Python.

For example,

class Singleton_base(object):
    _instance = None
    def __new__(class_, *args, **kwargs):
        if not isinstance(class_._instance, class_):
            class_._instance = object.__new__(class_, *args, **kwargs)
        return class_._instance

class Sample1(Singleton_base):
    def __init__(self):
        print("Object created.")

x = Sample1();
y = Sample1();
print(x,y)

Output:

Object created.
Object created.
<__main__.Sample object at 0x0000015E72D3F388> <__main__.Sample object at 0x0000015E72D3F388>

This is an effective method; however, there might be errors when multiple classes get involved due to multiple inheritances.

Use a Metaclass to Implement the Singleton Design Pattern in Python

A metaclass is a very interesting feature in Python since it can define the behavior of objects of a class. We can say that it is a class for a class.

In Python 2, we add the __metaclass__ attribute in a class. In Python 3, we can add it as an argument in the class.

We can use this feature to implement the Singleton design in Python.

For example,

class Singleton_meta(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton_meta, cls).__call__(*args, **kwargs)
        return cls._instances[cls]
    
class Sample(metaclass = Singleton_meta):
    def __init__(self):
        print("Object created.")

x = Sample();
y = Sample();
print(x,y)

Output:

Object created.
<__main__.Sample object at 0x0000015E72D3FF88> <__main__.Sample object at 0x0000015E72D3FF88>

This is a proper application of metaclass and achieves auto inheritance.

Use a Module to Implement the Singleton Design Pattern in Python

Probably the easiest and most basic implementation of Singletons in Python is by using a module.

We know that we can create modules in Python. A module that only contains functions can serve as a Singleton, and this is because it will bind all these functions to the module.

Author: Manav Narula
Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn