Этот вопрос проверяет знание способов реализации паттерна Синглтон в Python, который гарантирует существование только одного экземпляра класса.
Синглтон можно реализовать несколькими способами в Python. Самый простой — через переопределение метода __new__, который контролирует создание экземпляров. Другой популярный способ — использование декоратора класса, который сохраняет созданный экземпляр. Также можно использовать метаклассы для контроля процесса создания класса. В Python часто вместо явного Синглтона используют модули, так как они импортируются только один раз. Выбор способа зависит от требований к гибкости и сложности.
Паттерн Синглтон обеспечивает, что класс имеет только один экземпляр и предоставляет глобальную точку доступа к нему.
__new__class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
# Проверка
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # True - это один и тот же объектdef singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class DatabaseConnection:
def __init__(self):
print("Создание соединения с БД")
# Использование
db1 = DatabaseConnection() # Выведет "Создание соединения с БД"
db2 = DatabaseConnection() # Не выведет ничего - объект уже создан
print(db1 is db2) # Trueclass SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Logger(metaclass=SingletonMeta):
def __init__(self):
self.log_level = "INFO"Самый простой способ в Python — использовать модуль:
# config.py
class Config:
def __init__(self):
self.settings = {}
config = Config() # Создается один раз при импорте
# В другом файле
from config import config # Всегда получаем один и тот же объектВывод: Синглтон стоит использовать для ресурсоемких объектов (соединения с БД, кэши) или когда необходим строгий контроль над глобальным состоянием. В Python предпочтительнее использовать реализацию через модуль или декоратор, как наиболее читаемые и соответствующие философии языка.