Fundamentals 5 min read

Implementing the Singleton Pattern in Python: Multiple Approaches

This article explains the Singleton design pattern in Python and presents seven implementation techniques—including module‑level variables, module instances, decorators, metaclasses, class methods, and thread‑safe approaches—complete with code examples and guidance on choosing the appropriate method.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Implementing the Singleton Pattern in Python: Multiple Approaches

Singleton Pattern is a common software design pattern that ensures a class has only one instance throughout an application and provides a global access point.

1. Module-level variable – because a module is imported only once, a variable defined at module level naturally behaves as a singleton.

# singleton.py
class Singleton:
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

# usage
from singleton import Singleton
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True

2. Module-level instance – define an instance directly in a module and import that instance wherever needed.

# singleton_module.py
class SingletonClass:
    pass
singleton_instance = SingletonClass()

# usage
from singleton_module import singleton_instance
print(id(singleton_instance))  # same id each import

3. Decorator – a decorator can wrap a class to guarantee a single instance.

def singleton(cls):
    _instance = {}
    def inner():
        if cls not in _instance:
            _instance[cls] = cls()
        return _instance[cls]
    return inner

@singleton
class MyClass:
    pass

s1 = MyClass()
s2 = MyClass()
print(s1 is s2)  # True

4. Metaclass – a metaclass controls class creation and can store a single instance per class.

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

class SingletonViaMeta(metaclass=SingletonMeta):
    pass

s1 = SingletonViaMeta()
s2 = SingletonViaMeta()
print(s1 is s2)  # True

5. Class method – expose a class method that lazily creates and returns a single instance.

class SingletonClassMethod:
    __instance = None

    @classmethod
    def get_instance(cls):
        if not cls.__instance:
            cls.__instance = SingletonClassMethod()
        return cls.__instance

s1 = SingletonClassMethod.get_instance()
s2 = SingletonClassMethod.get_instance()
print(s1 is s2)  # True

6. __new__ with thread safety – protect instance creation with a lock to be safe in multithreaded environments.

import threading

class ThreadSafeSingleton:
    __instance = None
    _lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        with cls._lock:
            if not cls.__instance:
                cls.__instance = super().__new__(cls, *args, **kwargs)
        return cls.__instance

s1 = ThreadSafeSingleton()
s2 = ThreadSafeSingleton()
print(s1 is s2)  # True, thread‑safe

7. __new__ combined with metaclass – merge metaclass control with a lock for a clean, thread‑safe singleton.

class ThreadSafeSingletonMeta(type):
    _instances = {}
    _lock = threading.Lock()
    def __call__(cls, *args, **kwargs):
        with cls._lock:
            if cls not in cls._instances:
                cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class SingletonMetaSafe(metaclass=ThreadSafeSingletonMeta):
    pass

s1 = SingletonMetaSafe()
s2 = SingletonMetaSafe()
print(s1 is s2)  # True, thread‑safe

Conclusion – Python offers many ways to implement a singleton; the choice depends on personal preference, project requirements, and whether thread safety is needed. The examples above range from simple module‑level instances to advanced metaclass solutions.

PythonThread Safetydesign patternsingletonmetaclass
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.