Fundamentals 10 min read

Implementing Thread‑Safe Singleton Pattern in Python

This article explains the purpose of the Singleton design pattern, demonstrates multiple Python implementations—including module‑level singletons, decorators, class‑based approaches, __new__ method, and metaclass techniques—and shows how to add thread‑safety with locks to ensure only one instance exists across concurrent executions.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Implementing Thread‑Safe Singleton Pattern in Python

The Singleton pattern ensures that a class has only one instance throughout a program, which is useful for shared resources such as configuration objects.

Python offers several ways to implement a singleton:

Using a module (modules are naturally singletons because they are loaded once).

Using a decorator that caches the created instance.

Using a class with a class‑method that stores the instance.

Based on the __new__ method to control object creation.

Using a metaclass that overrides __call__ to return a single instance.

Module‑level singleton example:

<code class="language-python"># mysingleton.py
class Singleton(object):
    def foo(self):
        pass
singleton = Singleton()
</code>

Import and use the singleton directly:

<code class="language-python">from mysingleton import singleton
</code>

Decorator‑based singleton:

<code class="language-python">def Singleton(cls):
    _instance = {}
    def _singleton(*args, **kargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kargs)
        return _instance[cls]
    return _singleton

@Singleton
class A(object):
    a = 1
    def __init__(self, x=0):
        self.x = x
</code>

When multithreading is involved, the basic class‑method implementation can create multiple instances. Adding a lock solves this:

<code class="language-python">import time, threading

class Singleton(object):
    _instance_lock = threading.Lock()
    def __init__(self):
        time.sleep(1)
    @classmethod
    def instance(cls, *args, **kwargs):
        with Singleton._instance_lock:
            if not hasattr(cls, "_instance"):
                cls._instance = cls(*args, **kwargs)
        return cls._instance
</code>

Running multiple threads that call Singleton.instance() now prints the same object address, confirming thread‑safety.

__new__‑based singleton (thread‑safe):

<code class="language-python">import threading

class Singleton(object):
    _instance_lock = threading.Lock()
    def __init__(self):
        pass
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            with cls._instance_lock:
                if not hasattr(cls, "_instance"):
                    cls._instance = object.__new__(cls)
        return cls._instance
</code>

Instantiating Singleton() repeatedly returns the same object, even across threads.

Metaclass‑based singleton:

<code class="language-python">import threading

class SingletonType(type):
    _instance_lock = threading.Lock()
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            with SingletonType._instance_lock:
                if not hasattr(cls, "_instance"):
                    cls._instance = super(SingletonType, cls).__call__(*args, **kwargs)
        return cls._instance

class Foo(metaclass=SingletonType):
    def __init__(self, name):
        self.name = name
</code>

Both Foo('a') and Foo('b') refer to the same instance.

Overall, the article provides a comprehensive guide to creating singletons in Python and demonstrates how to make them safe for concurrent execution.

pythonThread SafetyDesign PatternLocksingletondecoratormetaclass
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

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.