How do you implement a singleton in Python, and what are the tradeoffs of different approaches?
Quick Answer
Common approaches: override `__new__` to always return the same instance, use a module (modules are already singletons — Python caches them in `sys.modules`), or use a metaclass that caches instances per class. The module-level approach is usually the simplest and most Pythonic; `__new__`-based and metaclass-based singletons add complexity that's rarely worth it outside of specific framework needs, and singletons in general are often better replaced by dependency injection for testability.
Detailed Answer
Approach 1: a module (the idiomatic Python singleton)
# config.py
_settings = {}
def get_settings():
if not _settings:
_settings.update(load_from_disk())
return _settings
Modules are imported once and cached in sys.modules, so any module-level
state is naturally a singleton — every importer sees the same object. This
is the simplest, most idiomatic option and is exactly what most "singleton"
needs in Python actually call for.
Approach 2: overriding __new__
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
a = Singleton()
b = Singleton()
a is b # True
__new__ runs before __init__ and is responsible for actually creating
the instance — by returning a cached instance instead of creating a new
one, every call to Singleton() returns the same object. Watch out:
__init__ still runs every time Singleton() is called (even on the
cached instance), so you typically need to guard re-initialization too.
Approach 3: a metaclass
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 Database(metaclass=SingletonMeta):
pass
This centralizes the singleton logic in one reusable metaclass rather than
duplicating __new__ in every class that needs it — useful if you have
many singleton classes, at the cost of adding metaclass complexity.
The tradeoff nobody skips: testability
Singletons introduce global mutable state, which makes unit tests
harder to isolate (tests can leak state into each other through the shared
instance) and makes dependency substitution awkward (you can't easily swap
in a fake Database for a test without monkeypatching the singleton).
The more commonly recommended alternative in modern Python code is
dependency injection: construct the shared object once (e.g., in
main() or an app factory) and pass it explicitly to whatever needs it,
rather than having classes reach out and grab a global singleton
themselves. This keeps the "there's only one" property where it's
genuinely needed (one process, one instance) while keeping tests able to
substitute a fresh instance per test.
Interview-ready summary: The simplest, most Pythonic singleton is just
a module-level object (modules are already cached singletons); __new__-
or metaclass-based singletons work but add complexity. In practice,
prefer constructing the shared object once and passing it explicitly
(dependency injection) over a true singleton, since global state makes
testing harder.