What It Is
The Singleton pattern makes sure a class has exactly one instance in the whole program, and gives everyone the same access point to it. Typical singletons: a configuration, a connection pool, a logger.
Python has a head start here: a module is imported only once, so an object created at module level is already a shared single instance. When creation should be lazy — done on first use, not at import — a classmethod like Config.instance() guards it: create on the first call, return the stored instance ever after.
Example: One Config for Everyone
The config is loaded on the first Config.instance() call and never again. Every caller receives the same object.
Load once with a guarded classmethod
The "loading config" line prints only once, although Config.instance() is called twice — and a is b proves both callers hold the same instance.
Output: complete Python program
class Config:
_instance = None
def __init__(self, app_name: str):
self.app_name = app_name
# The one instance is created on the first call, then reused.
@classmethod
def instance(cls) -> "Config":
if cls._instance is None:
print("loading config (happens once)")
cls._instance = cls("PromptCookbook")
return cls._instance
a = Config.instance()
b = Config.instance()
print("app:", a.app_name)
print("same instance:", a is b)
When to Use It
Use it when there really must be one of something: one loaded configuration, one connection pool, one cache — and creating it is expensive or duplicates would conflict.
Skip it when you can simply create the value once at the top of the program and pass it to whoever needs it. Passing dependencies openly is clearer than global access — the singleton is the last resort, not the first.
Pros and Cons
Pros: guaranteed single instance; lazy creation on first use; the module system gives the simple case almost for free.
Cons: it is a global in disguise — hidden dependencies make code harder to follow; tests cannot easily swap it for a fake; overuse leads to tangled programs.