Найти - Пользователи
Полная версия: Класс для синглтона
Начало » Python для экспертов » Класс для синглтона
1
kost-bebix
Здравствуйте. Хочу сделать, чтоб если класс синглтон (singleton) можно было не писать каждый раз

class A:
__single = None
def __init__(self):
# Singleton
if self.__class__.__single:
raise self.__class__.__single
self.__class__.__single = self
А просто наследовать уже готовый класс Singleton:

class A(Singleton):
pass
Вопрос: возможно ли это?
poltergeist
можно, но надо будет каждый раз в потомке вызывать инит предка. Я нашел вот такой пример с метаклассами, выглядит красиво, если надо, можно модифицировать под свои нужды:

class Singleton(type):
def __init__(cls, *args, **kw):
super(Singleton,cls).__init__(*args, **kw)
cls.instance = None
def __call__(cls, *args, **kw):
if cls.instance is None:
cls.instance = super(Singleton,cls).__call__(*args,**kw)
return cls.instance

#example:
class C:
__metaclass__ = Singleton

c1 = C()
print c1

c2 = C()
print c2


<__main__.C object at 0x00ABA950>
<__main__.C object at 0x00ABA950>
И ещё к прочтению: http://www.garyrobinson.net/2004/03/python_singleto.html
ZAN
kost-bebix
Здравствуйте. Хочу сделать, чтоб если класс синглтон (singleton) можно было не писать каждый раз
А просто наследовать уже готовый класс Singleton:
class A(Singleton):
pass

Вопрос: возможно ли это?
Очень даже возможно, при чем без метаклассов:
>>> class Singleton(object):
… __single = None
… def __new__(cls, *args, **kwargs):
… if cls.__single:
… raise Exception
… else:
… cls.__single = cls
… return cls

>>> class A(Singleton):
… pass

>>> class B(Singleton):
… pass

>>> a = A()
>>> aa = A()
Traceback (most recent call last):
File “<interactive input>”, line 1, in ?
File “<interactive input>”, line 5, in __new__
Exception
>>> b = B()
>>> bb = B()
Traceback (most recent call last):
File “<interactive input>”, line 1, in ?
File “<interactive input>”, line 5, in __new__
Exception
Тот же функционал можно было вынести и в инит, но в этом случае пришлось бы в каждом наследнике перевызывать конструктор родительского класса.
jan2ary
Вместо исключения одиночка должен возвращать экземпляр себя, созданный ранее.
playpauseandstop
jan2ary
Вместо исключения одиночка должен возвращать экземпляр себя, созданный ранее.
подписываюсь
Андрей Светлов
Не подписываюсь!
Синглетон - один из самых неоднозначных шаблонов проектирования. При возможности следует его избегать.
Как правило, подразумевают нечто вечное, создающееся без параметров и всегда годное к использованию.
Александреску предлагал феникс, уничтожающийся и возникающий опять при попытке обратиться.
Каждый трактует в силу своего разумения.

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

Использование синглетонов сильно осложняет тестирование (те же Банда Четырех, Бек, Фаулер, Александреску и Саттер, да и мой собственный опыт).

Стоит считать его испрользование признаком слабого дизайна (либо синглетон перерастает себя, являясь выражением более глубокого подхода - и тогда уже не важен разгово о способах его создания/получения).
PooH
Хороший готовый вариант синглетона - питоновский модуль ;)
Андрей Светлов
О!!!
Точно! Как-то я упустил это из виду.
Тем более что использование модуля не заставляет писать лишнее и не создает излишних иллюзий.
Если “в тему” - то просто и лаконично.
Если “уродливо” - то столь же наглядно вся уродливость вылезает наружу.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB