Уведомления

Группа в Telegram: @pythonsu

#1 Июль 16, 2016 12:27:29

lobster
От:
Зарегистрирован: 2011-06-09
Сообщения: 82
Репутация: +  0  -
Профиль   Отправить e-mail  

вопросы по паттерну Синглтон(Borg)

Всех приветствую!
Сама программа небольшая, но там дважды вызывается конфигурационный класс для извлечения некоторых переменных, я подумал будет лучше сделать этот класс синглтоном, чтобы один раз проинициализировав эти переменные, последующие вызовы не затрагивают эти переменные а просто возвращают эти переменные, ну вобщем нашел одну реализацию этого паттерна - Borg, вот пример:

 class Borg(object):
    __shared_state__ = {}
 
    def __init__(self):
        self.__dict__ = self.__shared_state__
 
class Singletone(Borg):
    def __init__(self, name=None):
        super(Singletone, self).__init__()
        if name:
            self.name = name
 
obj1 = Singletone('Hello, Borg!")
obj2 = Singletone()
print(obj1.name, obj2.name)
 
Вначале вошел в легкий ступор, как это значение переменной self.name оказывается в self.__shared_state__ после инициализации класса родителя, но потом понял что self.__dict__ = self.__shared_state__ это не присваивание, а передача указателя, выходит что при инициализации self.name = name в словарь self.__dict__ автоматом добавляется аттрибут self.name. Непонятно где хранится переменная __shared_state__ в каком объекте? Если к примеру попробовать удалить объект, то ничего не выйдет:

 obj1 = Singletone('Hello, Borg!")
del(obj1)
print(Singletone().name) # out -> Hello, Borg!



Офлайн

#2 Июль 16, 2016 13:07:41

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

вопросы по паттерну Синглтон(Borg)

Вообще не понял при чем здесь синглетон

Офлайн

#3 Июль 16, 2016 13:37:08

lobster
От:
Зарегистрирован: 2011-06-09
Сообщения: 82
Репутация: +  0  -
Профиль   Отправить e-mail  

вопросы по паттерну Синглтон(Borg)

4kpt_IV
Вообще не понял при чем здесь синглетон
Ану вобщем то да, лишний класс оказался ни кчему:
 class Borg(object):
    __shared_state__ = {}
 
    def __init__(self, name=None):
        self.__dict__ = Borg.__shared_state__
        if name:
            self.name = name
 
 
obj1 = Borg('Hello')
obj2 = Borg()
 
print(obj1.name, obj2.name)
 

Похоже просветление потихоньку приходит, __shared_state__ - это статический атрибут который можно получить не инициализировав класс



Офлайн

#4 Июль 16, 2016 14:54:51

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

вопросы по паттерну Синглтон(Borg)

https://ru.wikipedia.org/wiki/%D0%9E%D0%B4%D0%B8%D0%BD%D0%BE%D1%87%D0%BA%D0%B0_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)#Python
Хотя, создание нескольких объектов того, что должно быть единственным является логической ошибкой, имхо.

Офлайн

#5 Июль 17, 2016 17:28:42

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

вопросы по паттерну Синглтон(Borg)

а чем такой вариант плох?

 __all__ = ('config',)
 
class Config():
    pass
 
__config = None
 
def config():
    global __config
    if not __config:
        __config = Config()
    return __config

Или еще проще

 __all__ = ('config',)
 
class Config():
    pass
 
config = Config() 



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

Отредактировано PooH (Июль 17, 2016 17:33:18)

Офлайн

#6 Июль 17, 2016 17:29:52

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

вопросы по паттерну Синглтон(Borg)

lobster
Непонятно где хранится переменная __shared_state__ в каком объекте? Если к примеру попробовать удалить объект, то ничего не выйдет
В классе хранится.



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

Офлайн

#7 Июль 18, 2016 00:58:01

lobster
От:
Зарегистрирован: 2011-06-09
Сообщения: 82
Репутация: +  0  -
Профиль   Отправить e-mail  

вопросы по паттерну Синглтон(Borg)

Shaman
https://ru.wikipedia.org/wiki/%D0%9E%D0%B4%D0%B8%D0%BD%D0%BE%D1%87%D0%BA%D0%B0_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)#PythonХотя, создание нескольких объектов того, что должно быть единственным является логической ошибкой, имхо.
Да вообще, использовать синглтон это плохо, примерно также плохо как использовать глобальные переменные в коде.
Вот здесь тоже по теме https://rsdn.ru/forum/design/2615563.flat
PooH
В классе хранится.
Ну, до меня дошло, что класс это тоже объект.



Отредактировано lobster (Июль 18, 2016 01:00:56)

Офлайн

#8 Июль 18, 2016 10:07:11

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

вопросы по паттерну Синглтон(Borg)

lobster
Да вообще, использовать синглтон это плохо, примерно также плохо как использовать глобальные переменные в коде.
lobster
Сама программа небольшая, но там дважды вызывается конфигурационный класс для извлечения некоторых переменных, я подумал будет лучше сделать этот класс синглтоном
https://habrahabr.ru/post/125238/
 kk86 29 июля 2011 в 19:05
+11
Синглтон — зло, когда применён не к месту. Разве нет?
Doggy 29 июля 2011 в 19:09
+9
. . .
TheShock 29 июля 2011 в 21:48
+1
Проблема в том, что простота этого паттерна стала причиной ПОСТОЯННОГО применения Синглтона не к месту.
Хотя, вот лично я, не могу представить, когда он может быть нужен на практике.
В обозначенной ситуации обычно делаю что-то такое
 class Initializer:
 
    def __init__(self):
        self.initialized = False
 
    def init_by_need(self):
        if self.initialized:
            return
        # do initializations
        print('Init complete!')
        self.initialized = True
 
 
initializer = Initializer()
 
if __name__ == '__main__':
    for i in range(10):
        if i in [2, 5]:
            initializer.init_by_need()
Создавать несколько инициализаторов, или проверять их уникальность бессмысленно, поведение класса очевидно.

Отредактировано Shaman (Июль 18, 2016 10:10:19)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version