Форум сайта python.su
Есть замечательный паттерн программирования синглтон. Он гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.
Задался вот целью реализовать в питоне этот паттерн.
Получилось вот что:
Файл concon.py
import time, sys
class ConsoleController( object ):
_iInstance = None
class __Singleton:
_selfUsed = 0
_startTime = 0
_endTime = 0
_echoLevel=0
_indentStr = '\t'
def __init__(self):
self._startTime = self.getTime()
def __del__(self):
self._endTime = self.getTime()
timeElapsed = self._endTime - self._startTime
self \
.dropText('Script finished.') \
.dropText('Elapsed time: '+str(timeElapsed) + ' sec')
def getTime(self):
return time.time()
def cEcho(self,str):
sys.stdout.write(str)
return self
def dropLF(self):
self.cEcho('\n')
return self
def dropText(self,str,colorize=None):
self \
.dropIndent() \
.cEcho(str) \
.dropLF()
return self
def dropIndent(self):
self.cEcho(self._indentStr*self._echoLevel)
return self
def indentIncrease(self):
self._echoLevel += 1
return self
def indentDecrease(self):
self._echoLevel -= 1
if self._echoLevel < 0:
self._echoLevel = 0
return self
def __init__( self ):
if ConsoleController._iInstance is None:
ConsoleController._iInstance = ConsoleController.__Singleton()
self.__dict__['_EventHandler_instance'] = ConsoleController._iInstance
ConsoleController._iInstance._selfUsed += 1;
def __getattr__(self, aAttr):
return getattr(self._iInstance, aAttr)
def __setattr__(self, aAttr, aValue):
return setattr(self._iInstance, aAttr, aValue)
def __del__(self):
ConsoleController._iInstance._selfUsed -= 1
# print 'Links: ' + str(ConsoleController._iInstance._selfUsed)
if ConsoleController._iInstance._selfUsed == 0:
self._iInstance.__del__()
import concon
def diveIn(maxDeep=1,curDeep=0):
CC = ConsoleController()
CC.indentIncrease()
CC.dropText('In!')
if maxDeep>curDeep:
nextDeep = curDeep+1
diveIn(maxDeep,nextDeep)
CC.dropText('Out!')
CC.indentDecrease()
diveIn(4)
CC = ConsoleController()
CC.dropText('Destruct message will be shown after this line!')
Офлайн
http://python.su/forum/viewtopic.php?id=1786
http://www.iso.ru/journal/articles/143.html
Офлайн
PooHспасибо за ссылки, но проблему с
http://python.su/forum/viewtopic.php?id=1786
http://www.iso.ru/journal/articles/143.html
Sanovskiyэто не решило.
в начале скрипта просто необходимо обязательно создать инстанс ConsoleController иначе деструктор вложенного класса Singleton будет вызываться чаще одного раза.
Отредактировано (Июль 6, 2009 13:51:53)
Офлайн
sanovskiyЛучший синглтон в питоне это модуль.
Есть ли способ сделать код изящнее?
Офлайн
В качестве замены синглтону в питоне мне нравится метод Борга.
Офлайн
Я бы сделал так:
class Singleton(object):
instance_ref = None
def __new__(cls, *args, **kwargs):
if cls.instance_ref is None or cls.instance_ref() is None:
import weakref
instance = object.__new__(cls, *args, **kwargs)
cls.instance_ref = weakref.ref(instance)
if hasattr(cls, '__hidden_init__'):
cls.__init__ = cls.__hidden_init__
del cls.__hidden_init__
elif hasattr(cls, '__init__') and not hasattr(cls, '__hidden_init__'):
cls.__hidden_init__ = cls.__init__
cls.__init__ = lambda *args, **kwargs: None
return cls.instance_ref()
>>> a = Singleton()
>>> b = Singleton()
>>> a is b
True
Отредактировано (Июль 6, 2009 17:50:15)
Офлайн
Метод Борга очень изящный.
Офлайн
Спасибо за ответы.
Метод Борга действетельно изящен.
По сути, кого волнует id? :))
Офлайн