What is the Singleton Pattern in Python?

Discover the Singleton pattern in Python: definition, implementations with __new__, decorator and metaclass, best practices and practical use cases.
9 min read
Believemy logo

Definition of Singleton in Python

The Singleton is a design pattern that guarantees a class has only one single instance throughout your entire program. Every subsequent call to the constructor always returns the same instance, rather than creating a new one.

This pattern is part of the creational patterns described in the famous book Design Patterns: Elements of Reusable Object-Oriented Software by the Gang of Four. In Python, there are several elegant ways to implement it, which we will explore together in this article. If you want to deepen your knowledge of object-oriented programming, feel free to follow our comprehensive Python course.

Good to know

The Singleton is one of the most well-known design patterns, but also one of the most debated. It is essential to understand when to use it — and when to avoid it.


Why Use a Singleton?

The Singleton addresses a specific need: controlling access to a unique shared resource. Here are the most common use cases:

  • Database connection: you don't want to open multiple unnecessary connections.
  • Configuration file: a single object centralizes reading your application's configuration.
  • Logger: a unique entry point for writing log messages.
  • Application cache: a shared dict that stores temporary data.
  • Thread or connection pool: a unique manager that distributes resources.

The fundamental idea is that some objects only make sense if they exist as a single copy. Creating multiple instances of these objects could lead to inconsistencies, access conflicts, or resource waste.


Implementation with __new__

The most classic method for implementing a Singleton in Python is to override the __new__ method of your class. This special method is called before __init__ and controls the creation of the instance.

PYTHON
class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self, value=None):
        # Warning: __init__ is called on every call to Singleton()
        if value is not None:
            self.value = value


# Usage
a = Singleton("first")
b = Singleton("second")

print(a is b)       # True
print(a.value)      # second
print(id(a) == id(b))  # True

Let's analyze what happens step by step:

  1. On the first call Singleton("first"), _instance is None, so __new__ creates a new instance.
  2. Then, __init__ is called and assigns self.value = "first".
  3. On the second call Singleton("second"), _instance already exists, so __new__ returns the same instance.
  4. __init__ is called again, overwriting self.value with "second".
Warning

Warning: with this implementation, __init__ is called on every instantiation. If you place initialization logic there, it will be executed multiple times. Use a flag to control this.


Protected version with initialization flag

To prevent __init__ from being executed multiple times, you can add a control attribute:

PYTHON
class Singleton:
    _instance = None
    _initialized = False

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self, value=None):
        if not self._initialized:
            self.value = value
            self._initialized = True


a = Singleton("first")
b = Singleton("second")

print(a.value)  # first
print(b.value)  # first (same instance, not reinitialized)

This time, the value "first" is preserved because __init__ only executes once.


Implementation with a Decorator

A more Pythonic approach is to use a decorator. This decorator wraps any class and transforms it into a Singleton, without modifying its internal code:

PYTHON
def singleton(cls):
    instances = {}

    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return get_instance


@singleton
class Configuration:
    def __init__(self, file="config.yml"):
        self.file = file
        self.parameters = self._load()

    def _load(self):
        # Simulated loading
        return {"debug": True, "version": "1.0"}


# Usage
config1 = Configuration()
config2 = Configuration("other_config.yml")

print(config1 is config2)        # True
print(config1.file)              # config.yml
print(config2.parameters)        # {'debug': True, 'version': '1.0'}

This solution is elegant because it separates the Singleton logic from the business logic of the class. The decorator stores instances in a local dict, which even allows managing multiple independent Singleton classes.


Implementation with a Metaclass

For the most advanced cases, you can use a metaclass. A metaclass controls the creation of classes themselves, making it a powerful tool for the Singleton pattern:

PYTHON
class SingletonMeta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            instance = super().__call__(*args, **kwargs)
            cls._instances[cls] = instance
        return cls._instances[cls]


class Logger(metaclass=SingletonMeta):
    def __init__(self):
        self.messages = []

    def log(self, message):
        self.messages.append(message)
        print(f"[LOG] {message}")


# Usage
logger1 = Logger()
logger1.log("Application starting")

logger2 = Logger()
logger2.log("User connection")

print(logger1 is logger2)           # True
print(len(logger1.messages))        # 2
print(logger1.messages)             # ['Application starting', 'User connection']

The SingletonMeta metaclass intercepts the __call__ call (triggered when you write Logger()) and checks if an instance already exists. This approach is the most robust and works perfectly with inheritance.


Implementation with a Python Module

There is an even simpler approach, specific to Python: using a module as a Singleton. In Python, modules are single-instance objects by nature. When you import a module, Python loads it only once and caches it.

PYTHON
# file: my_singleton.py

class _Configuration:
    def __init__(self):
        self.debug = True
        self.version = "1.0"
        self.base_url = "https://example.com"

# Unique instance at module level
config = _Configuration()

def get_parameter(key):
    return getattr(config, key, None)
PYTHON
# file: main.py
from my_singleton import config, get_parameter

print(config.debug)              # True
print(get_parameter("version"))  # 1.0

# Everywhere in your code, config is the same instance
config.debug = False

This approach is often recommended by the Python community because it is simple, readable, and idiomatic. No need for a complex class or metaclass.


Comparison of Different Approaches

MethodComplexityInheritanceThread-safePythonic
__new__Medium⚠️ Partial❌ No✅ Yes
DecoratorLow❌ No❌ No✅ Yes
MetaclassHigh✅ Yes❌ No⚠️ Advanced
ModuleVery lowN/A✅ Yes*✅✅ Very

* Python's import mechanism is thread-safe by default thanks to the GIL.


Thread-safe Singleton

If your application is multi-threaded, classic Singleton implementations are not safe. Two threads could pass the if _instance is None check simultaneously. Here is a thread-safe version with a lock:

PYTHON
import threading


class SingletonThreadSafe:
    _instance = None
    _lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            with cls._lock:
                # Double-checked locking
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        pass


# Test with multiple threads
def create_instance():
    instance = SingletonThreadSafe()
    print(f"Thread {threading.current_thread().name}: {id(instance)}")


threads = [threading.Thread(target=create_instance) for _ in range(10)]
for t in threads:
    t.start()
for t in threads:
    t.join()

Double-checked locking is an optimization technique: the first if avoids acquiring the lock unnecessarily if the instance already exists, while the second if (inside the with) ensures thread safety.


Practical Example: Database Manager

Let's look at a realistic example of using the Singleton to manage a database connection:

PYTHON
import sqlite3
import threading


class DatabaseManager(metaclass=SingletonMeta):
    def __init__(self, db_path="app.db"):
        self.db_path = db_path
        self._connection = None
        self._lock = threading.Lock()

    @property
    def connection(self):
        if self._connection is None:
            self._connection = sqlite3.connect(self.db_path)
        return self._connection

    def execute(self, query, params=None):
        with self._lock:
            cursor = self.connection.cursor()
            if params:
                cursor.execute(query, params)
            else:
                cursor.execute(query)
            self.connection.commit()
            return cursor

    def fetch(self, query, params=None):
        cursor = self.execute(query, params)
        return cursor.fetchall()

    def close(self):
        if self._connection:
            self._connection.close()
            self._connection = None


# Usage throughout the application
db = DatabaseManager("my_application.db")
db.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")
db.execute("INSERT INTO users (name) VALUES (?)", ("Alice",))

# Elsewhere in the code, same instance
db2 = DatabaseManager()
results = db2.fetch("SELECT * FROM users")
print(results)  # [(1, 'Alice')]

Here, no matter where you instantiate DatabaseManager() in your code, you always get the same connection. This avoids opening multiple unnecessary connections and centralizes database management.


Best Practices and Caveats

When to Use the Singleton

  • You need a unique global access point to a resource.
  • Object creation is expensive (network connection, file reading).
  • The object must maintain a consistent state shared across multiple parts of the code.


When to Avoid the Singleton

  • Unit tests: the Singleton introduces global state that makes tests difficult to isolate. Prefer dependency injection.
  • Tight coupling: classes that depend on a Singleton are coupled to its implementation.
  • Single responsibility principle violation: the Singleton manages both its business logic and its lifecycle.
  • No state needed: if your class has no state, simply use functions at the module level.
Warning

The Singleton is sometimes called an anti-pattern in the Python community. Before using it, ask yourself whether a simple module or dependency injection would be more appropriate.


Tips for a Good Implementation

  1. Prefer the module approach for simple cases — it's the most Pythonic way.
  2. Use the metaclass if you need inheritance or a strict object-oriented structure.
  3. Protect concurrent access with a lock (threading.Lock) in a multi-threaded environment.
  4. Document clearly that your class is a Singleton — add an explicit docstring.
  5. Provide a reset method to facilitate unit testing.
PYTHON
class Singleton:
    """Singleton class — only one instance is created.
    
    Use Singleton.reset() in tests to reinitialize the instance.
    """
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    @classmethod
    def reset(cls):
        """Reset the instance (useful for testing)."""
        cls._instance = None


Frequently Asked Questions

Question

What is the difference between a Singleton and a global variable?

A global variable is simply a value accessible everywhere, without any control over its creation or modification. The Singleton, on the other hand, encapsulates the creation logic and guarantees that only one instance exists. It provides strict control through the class itself, while a global variable can be overwritten at any time.


Question

Does the Singleton work with inheritance in Python?

It depends on the implementation. With the __new__ method, inheritance can cause issues because the _instance attribute is shared. With a metaclass, each subclass will have its own entry in the _instances dictionary, which allows one Singleton per class in the inheritance hierarchy.


Question

Is the Singleton thread-safe in Python?

No, classic implementations are not thread-safe. Even though the GIL (Global Interpreter Lock) offers some protection, it does not guarantee the atomicity of the check and creation. For a thread-safe Singleton, use a threading.Lock with the double-checked locking pattern, or opt for the module approach which is naturally thread-safe.


Question

How can I learn to master design patterns in Python?

Design patterns like the Singleton become natural with practice and a solid understanding of object-oriented programming in Python. We recommend following our Python course on Believemy, which covers classes, metaclasses, and software design best practices in depth. You will learn to choose the right pattern for each concrete situation.

Related terms

Discover our python glossary

Browse the terms and definitions most commonly used in development with Python.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.