Одиночка гарантирует, что у класса ровно один экземпляр, и даёт всем глобальную точку доступа к нему. Он подходит для того, что действительно существует в одном экземпляре на процесс (конфигурация, логгер, пул соединений), но это и самый критикуемый паттерн: глобальный объект с изменяемым состоянием.
Config() и получают один экземплярСпособ 1: объект уровня модуля
Модуль выполняется один раз и кэшируется в sys.modules. Объект, созданный на уровне модуля, уже одиночка: каждый from config import settings возвращает один и тот же объект. Это самый питоничный способ, кода паттерна не нужно.
# --- config.py ---
class _Settings:
def __init__(self):
self.debug = False
settings = _Settings() # created once, at the first import of config
# --- a.py and b.py both do: from config import settings ---
a = settings
b = settings
a.debug = True
print(b.debug, a is b)True TrueСпособ 2: __new__
__new__ создаёт объект, поэтому может вернуть сохранённый экземпляр. Ловушка: Python вызывает __init__ после каждого Config(), и обычный __init__ сбросит состояние общего объекта.
class Config:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self): # runs on EVERY Config() call!
self.debug = False
a = Config()
a.debug = True
b = Config()
print(a is b, b.debug)True False