Events - Design Patterns

  • Thread starter Gianmaria Iaculo - NVENTA
  • Start date
G

Gianmaria Iaculo - NVENTA

Hi there,
i found a nice article about a custom implementation of events by Duncan
Booth here:

http://www.suttoncourtenay.org.uk/duncan/accu/pythonpatterns.html#observer


The code is here:

STEP 1) Define a Delegate Class

class Delegate:
'''Handles a list of methods and functions
Usage:
d = Delegate()
d += function # Add function to end of delegate list
d(*args, **kw) # Call all functions, returns a list of results
d -= function # Removes last matching function from list
d -= object # Removes all methods of object from list
'''
def __init__(self):
self.__delegates = []

def __iadd__(self, callback):
self.__delegates.append(callback)
return self

def __isub__(self, callback):
# If callback is a class instance,
# remove all callbacks for that instance
self.__delegates = [ cb
for cb in self.__delegates
if getattr(cb, 'im_self', None) != callback]

# If callback is callable, remove the last
# matching callback
if callable(callback):
for i in range(len(self.__delegates)-1, -1, -1):
if self.__delegates == callback:
del self.__delegates
return self
return self

def __call__(self, *args, **kw):
return [ callback(*args, **kw)
for callback in self.__delegates]STEP 2) Define the Event
Classclass Event(property):
'''Class event notifier
Usage:
class C:
TheEvent = Event()
def OnTheEvent(self):
self.TheEvent(self, context)

instance = C()
instance.TheEvent += callback
instance.OnTheEvent()
instance.TheEvent -= callback
'''
def __init__(self):
self.attrName = attrName = "__Event_" + str(id(self))
def getEvent(subject):
if not hasattr(subject, attrName):
setattr(subject, attrName, Delegate())
return getattr(subject, attrName)
super(Event, self).__init__(getEvent)

def call(self, subject, *args, **kw):
if hasattr(subject, self.attrName):
getattr(subject, self.attrName)(subject, *args, **kw)

STEP 3) Use this logic in an object (ObjectA)class ClockTimer:
def GetHour(self):
return self._hour
def GetMinute(self):
return self._minute
def GetSecond(self):
return self._second

TickEvent = Event()
def OnTick(self):
ClockTimer.TickEvent.call(self, self.GetHour(),
self.GetMinute(), self.GetSecond())

def Tick(self):
# update internal time-keeping state
# ...
self.OnTick()
STEP 4) Subscribe the ObjectA Event and react...class DigitalClock(Widget):
def __init__(self, clockTimer):
self.__subject = clockTimer
clockTimer.TickEvent += self.Update

def close(self):
self.__subject.TickEvent -= self.Update

def Update(self, subject, hour, min, sec):
self.displayedTime = (hour, min, sec)
self.Draw()

def Draw(self):
# draw the digital clock
I've tried to use it but i failed. From mypoint of view my event is never
been fired and it seem that my event subscription is not accepted and my
OnTick Event never raise to execute the Update method,i've made some changes
to the original code.. jjust inserted a timer to have this event fired many
times:class ClockTimer: _hour = 1 _minute = 1 _second = 1
_timer = Timers.timer(0) def __init__(self):
self._timer.start(10) while 1:
if(self._timer.isexpired()): self._hour = self._hour + 1
self._minute = self._minute +1 self._second = self._second +1
self.Tick() self._timer.start(10)
def getHour(self): return self._hour def getMinutes(self):
return self._minute def getSecond(self): return self._second
TickEvent = Event() def OnTick(self):
ClockTimer.TickEvent.call(self, self.getHour(), self.getMinutes(),
self.getSecond()) def Tick(self): print "Tick in CLockTimer"
self.OnTick()and a little modification to the object that uses this
event:class DigitalClock(): clockTimer = ClockTimer() def
__init__(self): clockTimer.TickEvent += self.update def
close(self): self.__subject.TickEvent -= self.update def
update(self, subject, hour, min, sec): print hour print min
print secthe code is really eas as you can see... so in the main i added
this simpleline of code...c = DigitalClock()but nothing really happen... i'm
sure i'm going wrong somewhere.. but cant understand where...any Idea???I've
tried to ask to Duncan directly by mail.. but the reported mail address is
no more valid...Someone used this?? Someone uses an other way for events???
Regards,Gianmaria
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top