Задался вот целью реализовать в питоне этот паттерн.
Получилось вот что:
Файл 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__()
Есть ли способ сделать код изящнее? Очень напрягает оперирование свойством _selfUsed
Плюс вследствие этого в начале скрипта просто необходимо обязательно создать инстанс ConsoleController иначе деструктор вложенного класса Singleton будет вызываться чаще одного раза.
Вот например в этом случае:
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!')