Welcome, guest | Sign In | My Account | Store | Cart

when adding callbacks, the code may not be very focused on the actual problem. A solution si to write a generic base class to deal with the callbacks issues, and then decorate the methods with the event for wich you want a binding.

Python, 54 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class CallbackBase:
   def __init__(self):
	self.__callbackMap = {}
	for k in (getattr(self, x) for x in dir(self)):
	    if hasattr(k, "bind_to_event"):
		self.__callbackMap.setdefault(k.bind_to_event, []).append(k)
	    elif hasattr(k, "bind_to_event_list"):
		for j in k.bind_to_event_list:
		    self.__callbackMap.setdefault(j, []).append(k)
	
    ## staticmethod is only used to create a namespace
   @staticmethod
   def callback(event):
	def f(g, ev = event):
	    g.bind_to_event = ev
	    return g
	return f
 
   @staticmethod
   def callbacklist(eventlist):
	def f(g, evl = eventlist):
	    g.bind_to_event_list = evl
	    return g
	return f
 
   def dispatch(self, event):
	l = self.__callbackMap[event]
	f = lambda *args, **kargs: \
	    map(lambda x: x(*args, **kargs), l)
	return f

## Sample
class MyClass(CallbackBase):
   EVENT1 = 1
   EVENT2 = 2
 
   @CallbackBase.callback(EVENT1)
   def handler1(self, param = None):
	print "handler1 with param: %s" % str(param)
	return None
 
   @CallbackBase.callbacklist([EVENT1, EVENT2])
   def handler2(self, param = None):
	print "handler2 with param: %s" % str(param)
	return None
 
   def run(self, event, param = None):
	self.dispatch(event)(param)
	
 
if __name__ == "__main__":
   a = MyClass()
   a.run(MyClass.EVENT1, 'mandarina')
   a.run(MyClass.EVENT2, 'naranja')

Here is a sample class which has two events: EVENT1 and EVENT2, and we have 2 handlers, handler1 is register to EVENT1 and handler2 will be called either for EVENT1 or EVENT2. The run method is MyClass's main loop, and will dispatch event for the corresponding event. This will return a function, and we can pass the arguments we wanto to the function. A list with all the returned value will be return

Maybe, a more elegant solution can be implement using Metaclasses

Created by Javier Burroni on Tue, 3 Jul 2007 (PSF)
Python recipes (4591)
Javier Burroni's recipes (3)

Required Modules

  • (none specified)

Other Information and Tasks