Одиночка гарантирует, что у класса ровно один экземпляр, и даёт всем глобальную точку доступа к нему. Он подходит для того, что действительно существует в одном экземпляре на процесс (конфигурация, логгер, пул соединений), но это и самый критикуемый паттерн: глобальный объект с изменяемым состоянием.

Три модуля вызывают `Config()` и получают один экземпляр
Три модуля вызывают Config() и получают один экземпляр

Способ 1: объект уровня модуля

Модуль выполняется один раз и кэшируется в sys.modules. Объект, созданный на уровне модуля, уже одиночка: каждый from config import settings возвращает один и тот же объект. Это самый питоничный способ, кода паттерна не нужно.

python
# --- 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)
text
True True

Способ 2: __new__

__new__ создаёт объект, поэтому может вернуть сохранённый экземпляр. Ловушка: Python вызывает __init__ после каждого Config(), и обычный __init__ сбросит состояние общего объекта.

python
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)
text
True False