A singleton is a class that has only one object. Every time you call the class, you get that same object back. It is used for things the whole program should share, such as one settings object or one connection pool.
The program
class Settings: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) cls._instance.values = {"theme": "light"} # set up only once return cls._instance a = Settings() b = Settings() a.values["theme"] = "dark" print(a is b) print(b.values["theme"])
True dark
How it works
__new__is the method that creates a new object. Python calls it before__init__. Here it creates an object the first time, stores it in the class variable_instance, and returns the stored object on every later call.a is bisTrue: both names point to the same object. A change made throughais visible throughb.- The set-up is inside the
if, not in__init__. Python calls__init__on everySettings()call, even when__new__returned the old object, so an__init__would reset the values each time.
The __init__ problem
class Settings: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def __init__(self): self.values = {"theme": "light"} a = Settings() a.values["theme"] = "dark" b = Settings() # runs __init__ again print(a.values["theme"])
light
A simpler way: a module
A Python module is loaded only once. Every import settings in the program gets the same module object. So a module with variables at the top level already behaves like a singleton:
# settings.py theme = "light"
Any file can then use import settings and settings.theme = "dark", and every other file sees the change. Many Python programmers prefer this to a singleton class, because it needs no extra code.