8

101 игра на python. Шпаргалки. Синглтон (Singleton) в Python

Серия Шпаргалки

В Python, синглтон – это шаблон проектирования, который гарантирует, что у класса будет только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру. Это значит, что при попытке создать новый объект этого класса, ты всегда будешь получать один и тот же объект.

Синглтоны полезны, когда нужно ограничить количество экземпляров класса, например:

  • Для управления подключением к базе данных (чтобы не открывать много подключений).

  • Для хранения глобальной конфигурации приложения (чтобы все части приложения использовали одну и ту же конфигурацию).

  • Для логгирования (чтобы все сообщения шли в один файл).

Преимущества синглтона:

  • Гарантия единственного экземпляра: Синглтон гарантирует, что класс будет иметь только один экземпляр. Это полезно для управления ресурсами, которые должны быть уникальными.

  • Глобальный доступ: Синглтон предоставляет глобальную точку доступа к экземпляру класса, что упрощает использование этого экземпляра в любой части программы.

Недостатки синглтона:

  • Глобальное состояние: Синглтон может привести к использованию глобального состояния, что может вызывать неожиданные побочные эффекты и усложнять тестирование.

  • Нарушение принципов ООП: Синглтон может нарушать принцип единственной ответственности и инкапсуляции.

Несколько способов реализации синглтона в Python.

1. Реализация Через переопределение метода __new__

  • Mетод __new__ отвечает за создание экземпляра класса. Переопределив его, я смогу контролировать этот процесс.

  • В этом примере я буду хранить единственный экземпляр класса в переменной _instance.

  • Если экземпляра еще нет, я его создам, иначе верну уже существующий экземпляр.

2. Реализация Через декоратор

  • Декоратор – это функция, которая модифицирует класс.

  • В этом примере я создаю функцию-декоратор singleton, которая принимает класс и возвращает его обернутую версию.

  • Внутри декоратора я храню экземпляры классов в словаре instances.

  • Если экземпляр класса еще не создан, я его создам и сохраню в словаре, иначе верну существующий экземпляр.

3. Реализация Через метакласс

  • Mетакласс позволяет контролировать создание классов.

  • В этом примере я создам метакласс SingletonMeta, который будет следить за созданием экземпляров.

  • Метакласс хранит экземпляры классов в словаре _instances.

  • При создании нового экземпляра, я проверяю, есть ли он уже в словаре, если нет – создаю, иначе возвращаю существующий экземпляр.

4. Реализация Через модуль

  • В Python модуль сам по себе является синглтоном.

  • Я могу создать объект в модуле, и он будет единственным экземпляром.

Когда использовать синглтон?

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

  • Когда тебе требуется глобальный доступ к этому объекту.

Оригинала статьи в GIT

Другие шпаргалки:

Структуры данных в python
Переменные в python: что, как и зачем нужны
Строки в python
Функции в python

Серия 101 игра на python с разбором кода. Портирую классические игры на язык python с добавлением искусственного интеллекта.

Серия информатика, с изложением терминов

UPD:

КОД ПЕРЕЕХАЛ ПО ЭТОМУ АДРЕСУ

Правила сообщества

Публиковать могут пользователи с любым рейтингом. Однако!


Приветствуется:

• уважение к читателям и авторам

• конструктивность комментариев

• простота и информативность повествования

• тег python2 или python3, если актуально

• код публиковать в виде цитаты, либо ссылкой на специализированный сайт


Не рекомендуется:

• допускать оскорбления и провокации

• распространять вредоносное ПО

• просить решить вашу полноценную задачу за вас

• нарушать правила Пикабу

1
Автор поста оценил этот комментарий

В разработке приложений - возможно. В автоматизации тестирования, особенно UI тестирования, синглтон нужен, потому что забудем уж о лишних окнах браузера, но каждый мудак норовит открыть пяток подключений к базе и начать срать туда непоследовательно и возможно без логирования созданных в ходе теста данных.

И даже не ты, а твои коллеги с низкой культурой кода создают объекты где попало и необходимо чтобы система боролась с чужими подходами к написанию кода и жёсткому приведению некоторых вещей к одному виду.

И да, благодаря больному воображению и кривым рукам объекты создаются десятки раз в случайных местах кода, впрочем обычно очевидных, это билдеры для некоторых классов, page object классы и ряд других. Что с одной стороны облегчает поиск, с другой я гарантирую что в АТ-фреймворке на тысячу тестов логеры, подключение к базе, и некоторые парсеры создаются в нескольких экземплярах и неположенных местах.


эм, и да, глобалки у автоматизаторов - норма. Например конфиг драйвера, некоторые общие для энвов данные. А вот отказ от них сулит часовой квест с поиском места где использовались локальные значения, хотя на первом этапе квест называется "а почему тест падает?"

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Добавлю. При массивном скраппинге - мастхэв

0
Автор поста оценил этот комментарий

Самые последние строки в logger.py:


#logger = Logger(info_log_path='info.log', debug_log_path='debug.log', errors_log_path='errors.log', json_log_path='log.json')

logger = Logger()

говорят о том, что вы сами не определились, предлагаеть ли пользователю логгера использовать `Logger()` для фальшивого создания объекта (которые на самом деле создаётся только раз) или использовать глобальную переменную `logger`. Если пользователь использует переменную, зачем вообще все эти махинации с метаклассом? Создали переменную и используйте её, где хотите. Если нужет метакласс, чтобы заставить `Logger()` создавать объект только один раз, зачем переменная?


В этих же строках видна ещё одна нерешаемая проблема Синглтона. Паттерн предполагает, что программист не должен думать отдельно об инициализации объекта и отдельно о его использовании, но по факту инициализация таки произойдёт в момент первого вызова. А какой из вызовов - первый, не так легко определить. Если же определить первый вызов легко, весь Синглтон сводится к глобальной переменной, единожды инициализированной в глобальном контексте. Т.е. исчезает вся суть Синглтона, в которой инициализация делается в произвольной точке первого вызова.


При этом, когда все эти ваши файлы закрывать, остаётся неконтролируемым - когда-то в конце вместе со всем приложением. Нет возможности начать отключаться от каких-то ресурсов раньше, чем закрытие приложения.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Нет - же. Класс инициализируется один раз при запуске программы. Потом он так и висит в памяти неизменным. В коде есть строка `logger = Logger()`. По сути импорт from logger import logger уже гарантирует, что мы будем работать только с одном инстансом. Но я силой гарантирую, что не появится второй инстанс логгера.

Так я могу быть уверен, что работаю только с одним логгером в дальнейшем

Иллюстрация к комментарию
Автор поста оценил этот комментарий

В целом, синглтон не нужен никогда.


Когда тебе нужно, чтобы объект существовал в единственном экземпляре

Стоит добавить: "Но при этом ты не в состоянии создать единственный экземпляр в том единственном месте, где это нужно. Ты хочешь вызывать создание объекта десятки раз в случайных местах кода, и хочешь, чтобы система успешно боролась с твоей шизофренией, на самом деле создав объект только один раз. При этом из кода ты никогда не поймёшь, в каком из десятков фальшивых мест созданий объекта он на самом деле будет создан."


Когда тебе требуется глобальный доступ к этому объекту.

При том, что отсутсвие глобальных переменных считается просто обязательным свойством нормального кода.


И ещё не забываем, что автоматическое создание объекта в момент первого вызова делает теоретически невозможным какое-либо проектирование, когда же объект может быть удалён.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

У вас не умеют готовить Singleton


Вот тебе пример, где я использую singleton в коде своего логгера.


https://github.com/hypo69/hypo/blob/master/src/logger/logger...

С импортом в другие модули:
from src.logger import logger

показать ответы

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества