PITFALL
The Singleton is a Lie 🍰
Singleton is an anti-pattern that comes with a lot of drawback despite seeming like a good solution
PATTERN
Visitor Pattern (Double Dispatch)
Separate operations from object structures by externalizing behavior into visitor objects.
PATTERN
Python Property Decorator
The property decorator lets you use variables as getters and setters
PATTERN
ThreadPoolExecutor Result Mapping
Return the input value from workers so results can be mapped to tasks when using as_completed.
PATTERN
Correct IPv4 Sorting
String sorting produces incorrect ordering of IPv4 addresses. Convert to numeric tuples.
PITFALL
Regex Catastrophic Backtracking
Nested quantifiers can cause exponential regex execution time.
PATTERN
Parallel Netmiko SSH Execution
Use ThreadPoolExecutor to run Netmiko commands across many devices concurrently.
The Singleton is a Lie 🍰
pitfall
Singleton is an anti-pattern that comes with a lot of drawback despite seeming like a good solution
Singleton Metaclass
class Singleton(type): """ Usage: class ClassName(metaclass=Singleton) """ _instances = {} def __call__(cls, *args, **kwargs) -> Any: if cls not in cls._instances: instance = super().__call__(*args, **kwargs) cls._instances[cls] = instance return cls._instances[cls]Borg Variant
class Singleton: _state = {} # Using a class-variable makes it persist (shared) across object instances def __init__(self): self.__dict__ = self._stateModule-backed Singleton
class Config: def __init__(self): self.state: Union[Dict[str,Any],Bool] = False # Don't mind the typehint.. import_this = Config() #--------------------------------------------------- from config import import_this as config if not config.state: print("This is the most Pythonic (recommended) implementation")Pythons Builtin Logger (Multiton)
import logging _logger = logging.getLogger("app") # This is actually a registry-backed Multiton and ain't that bad def get_logger(): return _logger """ Use by importing the get_logger function """ EXPLANATION
Singleton enforces uniqueness by controlling instantiation. Python achieves the same effect more naturally by controlling module identity through the import system. This makes explicit Singleton patterns redundant in most cases. Singletons are typically an anti-pattern and adds hidden state, tight coupling and makes testability difficult. Moreover they introduce state that is hard to reason about because it can be mutated by anyone and tend to accumulate technical debt over time. Singleton is almost never the right answer, except in rare cases where you fully understand and consciously accept the tradeoffs.
NOTES
Singletons are a legacy pattern that solve a problem Python does not have. In Python, modules are loaded once and cached in sys.modules, meaning any object defined at module scope is already a process-wide singleton. Attempting to reintroduce Singleton patterns through metaclasses or class control adds unnecessary complexity while introducing hidden state, tight coupling, and poor testability. Most Singleton use-cases in Python are better solved with: - module-level instances - dependency injection - explicit lifecycle management As systems grow, Singleton-based designs tend to degrade into implicit, globally shared state that becomes difficult to reason about, test, and evolve.
GOTCHAS
Real-world failure modes: - Tests leak state between runs because the Singleton persists - Multiprocessing creates multiple “singletons” (one per process) - Hidden mutations from different parts of the system cause non-deterministic bugs - Refactoring becomes difficult because dependencies are implicit