473,398 Members | 2,403 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Events

Anyone want to comment on what they think of this following bit of a
simple event framework?
Are there any really obvious things I should be doing with this code
that stop me from getting bitten on the arse in the future?
class Talker:
def __init__( self ):
self.listeners= []

def AddListener( self, event, listener ):
self.listeners.append( [ event, listener ] )

def RemoveListener( self, event, listener ):
for i, ( e,l ) in enumerate( self.listeners ):
if (e == event ) and ( l==listener ):
self.listeners.pop( i )

def Talk( self, event, *args ):
for i in self.listeners:
evt, listener= i
if evt == event:
listener( *args )
class Listener:
def HeardSomething( self, message ):
print 'Listener.HeardSomething'
print message

class FoobarTalker( Talker ):
importantEvent= 42

def SomethingHappened( self, something ):
self.Talk( FoobarTalker.importantEvent, something )

l= Listener()
t= FoobarTalker()

t.AddListener( FoobarTalker.importantEvent, l.HeardSomething )
t.SomethingHappened( 'something' )
t.RemoveListener( FoobarTalker.importantEvent, l.HeardSomething )
-Factory
Jul 18 '05 #1
5 1448
factory wrote:
Anyone want to comment on what they think of this following bit of a
simple event framework?
Are there any really obvious things I should be doing with this code
that stop me from getting bitten on the arse in the future? .... class FoobarTalker( Talker ):
importantEvent= 42

def SomethingHappened( self, something ):
self.Talk( FoobarTalker.importantEvent, something ) ....

Rather than making events be numbers (simple discrete things),
I suspect that you'd be happier with a hierarchy. This way
You can listen to "all kinds of events."

Python gives you a nice way to define hierarchies in classes,
so you could use classes directly as your events, or make
your events instances (and thus allow data to be attached to
the event). Certainly if you are attaching data, and possibly
even if you you are not, you may want to provide a means of
retrieving "the current event." You could even look at the
history of exceptions in python for a model of what you might want.

So, for events:
class Event(object): pass # The mother event in case you need to share
class ImportantEvent(Event): pass
class IgnorableEvent(Event): pass
class UsefulEvent(Event): pass

you could change the guts of your Talk method from:
.... evt, listener = i
if evt == event:
listener(*args)

To:
....
criterion, listener = i
if issubclass(event, criterion):
listener(*args)

Or (for the data-attached form):
criterion, listener = i
if isinstance(event, criterion):
listener(*args)
....
Jul 18 '05 #2
> Are there any really obvious things I should be doing with this code

You might want to think about defining an event class. There's a
cookbook recipe that addresses this kind of thing. It is at
http://aspn.activestate.com/ASPN/Coo.../Recipe/286136

I've been playing with a little program that I'm going to use in a
paper on event-driven programming. It uses an event-class. Also uses
a set rather than a list to hold the list of
observers/subscribers/listeners:

************************************************** *************

import sets

class Dispatcher:
def __init__( self ):
# initialize a set of observers
# each observer includes the event-type that
# it wants to observer
self.myEventHandlers = sets.Set()

def registerHandler( self, argEventHandler, argEventType ):
self.myEventHandlers.add( (argEventHandler, argEventType) )

def eventArrival(self, argEvent):
# dispatch the event to the registered handlers
self.notifyEventHandlers(argEvent)

def notifyEventHandlers( self, argEvent):
for anEventHandler, anEventType in self.myEventHandlers:
if anEventType == argEvent.myEventType:
# if the observer is registered for this type of event...
anEventHandler.handle(argEvent) # ...send the event to it

class Event:
def __init__(self, argEventType, argEventSource):
self.myEventType = argEventType
self.myEventSource = argEventSource

class EventHandler:
def __init__(self, argHandlerName):
self.name = argHandlerName

def handle(self, argEvent ):
# for this simple example, all we do to handle
# the event is print information about it
print self.name , "is handling a", argEvent.myEventType, \
"event from" , argEvent.myEventSource
# create a dispatcher
demoDispatcher = Dispatcher()

# create some event handlers
demoHandler1 = EventHandler("Larry")
demoHandler2 = EventHandler("Moe ")
demoHandler3 = EventHandler("Curly")

# define an event type
demoEventType = "LeftMouseDoubleClick"

# register the event handlers for that type of event
demoDispatcher.registerHandler( demoHandler1, demoEventType )
demoDispatcher.registerHandler( demoHandler2, demoEventType )
demoDispatcher.registerHandler( demoHandler3, demoEventType )

# generate an actual event
demoEvent = Event(demoEventType, "mouse") # "mouse" is the event
source

# send the event to the dispatcher
demoDispatcher.eventArrival(demoEvent)

************************************************** **************
Jul 18 '05 #3
factory <t@t.com> writes:
Anyone want to comment on what they think of this following bit of a
simple event framework?


You should definitely look into the dispatcher module:

http://aspn.activestate.com/ASPN/Coo...n/Recipe/87056

The comments indicate that an enhanced version is maintained on SF.

Thomas
Jul 18 '05 #4

"factory" <t@t.com> wrote in message
news:MPG.1c08708d5ec6746c989688@news-server...
Anyone want to comment on what they think of this following bit of a
simple event framework?


Since there can be multiple listeners for a particular type of event, I
would use an event-listener dict with event as key and list of listeners as
the value. This simplifies the code. Plus, linearly scanning a list of
event listener pairs to respond to an event (or deregister) will bite when
the list gets long enough. So, in __init__,
self.listeners = {}

For AddListener, the handy idiom for appending a new listener to a possibly
non-existent list of current listeners is
self.listeners.get(event, []).append(listener)
(If you cannot other wise guarantee that listeners only try to register for
a particular event once, you might want to add a check here.)

The body of Talk is then the much simpler
for listener in self.listeners[event]:
listener( *args )

If you can guarantee that listeners are only registered once for an event,
then deletion is also simple: self.listeners[event].remove(listener)

Terry J. Reedy


Jul 18 '05 #5
Terry Reedy wrote:
For AddListener, the handy idiom for appending a new listener to a possibly
non-existent list of current listeners is
self.listeners.get(event, []).append(listener)


This bit doesn't actually work.

When event isn't found in self.listeners, you create a new, empty
list.... but that list is never bound as a value in self.listeners. And
even if you add a 'self.listeners = ...' to that line, you'll still have
the problem that list.append() returns None -- you'll overwrite
self.listeners with that None.

If you use listeners.setdefault() instead, though, it works just as you
have it --
listeners = {}
listeners.setdefault('OnClick', []).append('foo')
listeners {'OnClick': ['foo']}


The difference between get() and setdefault() seems to be that get()
simply returns a sentinel value if the requested key is missing, but
setdefault() will create a key and assign that value to it, and then
return the (default) value of the (new) key.

Jeff Shannon
Technician/Programmer
Credit International
Jul 18 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Sasha | last post by:
Hi everyone, Here is my problem: I have the following classes: - DataNode - this class is designed to hold some data and will be contained in a tree like data structure DataTree. When...
6
by: Saso Zagoranski | last post by:
Hi! How can I unregister all the events registered to a control? I have seen a piece of code in another thread, which gets all the registered handlers for a specific event. Let's say I have a...
14
by: JPRoot | last post by:
Hi I use the following syntax to have events inherited from base to child classes which works nicely (virtual and override keyword on events). But I am wondering if it is a "supported" way of using...
2
by: Bob Rundle | last post by:
I have the following code, which appears to be working. However it doesn't look right. The part I am wondering about is the logic in DisconnectEvents(). This logic creates a new delegate and...
4
by: LP | last post by:
Hello! I am still transitioning from VB.NET to C#. I undertand the basic concepts of Delegates, more so of Events and somewhat understand AsyncCallback methods. But I need some clarification on...
11
by: Nicky Smith | last post by:
Hello, I'm studying a book on VB.net Win apps, and I'm reading a section on events and delegates and raising events. Is it just me, or is this not just subs dressed up as something else? I...
30
by: Burkhard | last post by:
Hi, I am new to C# (with long year experience in C++) and I am a bit confused by the language construct of events. What is it I can do with events that I cannot do with delegates? At the moment...
5
by: Richard Maher | last post by:
Hi, Here I mean "User" in the Programmer or Javascript sense. I merely wish to programmatically trigger an Event. It would be absolutely fantastic if there was a (Form level?) ONUSEREVENT() and...
14
by: xoozlez | last post by:
Hi there, I have a registration form where I like to filter out the past events of 2007. This is the code I am using : strSQL = "SELECT EventID, EventName, EventDateBegin, EventDateEnd,...
1
by: swethak | last post by:
Hi, I am desiging the calendar application for that purpose i used the below code. But it is for only displys calendar. And also i want to add the events to calendar. In that code displys the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.