From: Mike C. F. <mcf...@ro...> - 2005-10-06 13:48:15
|
Ian Bicking wrote: >Hi. I'm thinking about adding an event system to SQLObject, and was >thinking about using PyDispatcher for that. But I often want to >dispatch based on the class of the object (aka sender), not the >instance, and usually based on isinstance/issubclass, not identity. >Events would be fired for basic operations like subclassing and >instantiation. > >Well... as I'm thinking about it, I could just not use instance senders, >and always send based on the class. And then I could set up a listener >for a subclassing event, and clone all the listeners for the superclass >to also listen to the subclass. Anyway, curious if anyone else has done >something similar. > > Not with classes, but this is the same basic pattern as for a tree-of-events approach. Because we want to use hashes for speed internally you would use the __mro__ (or manually created equivalent for a classic class) to serially dispatch messages at ever-decreasing specificity (superclass-levels): for cls in type(sender).__mro__(): results.extend( dispatcher.send( sender=cls, signal=signal, instance=sender, **named ) ) The biggest problem with all of these things is that they tend to be application/domain specific. For instance, many times you want to do the same thing with trees-of-signals instead of trees-of-classes. Similarly you may want to be able to allow exiting from the loop at some point. Oh, regarding the subclassing and instantiation signals, subclassing would just be a signal sent from a metaclass initialiser. Similarly instantiation would just be an instance initialiser-sent signal. >The other thing I'm wondering about is how listeners can communicate >back. There doesn't seem to be any way to cancel the event or cancel >the other listeners, for instance -- I suppose a simple way would be to >raise an exception, and after all not all events can be cancelled anyway >(represented by the presence of lack of a try:except: around the line >that raises the event). Another thought for communication is that the >event contain a mutable argument. For instance, on a create-instance >event the keyword argument dictionary could be passed in, and listeners >could modify it. But again, curious if anyone has patterns they are >used to. > > Not personally, I tend to use dispatcher for sending "observable" events, more than UI-interaction-style events. That is, my events are generally used for notification-of-change, not so much bubbling "find a handler" operations. As for how to implement it, a simple "StopIteration"-like class taking a result as a parameter might be the best approach (rather than an exception). We'd need support in send for that, no big deal, just an "if isinstance(result, StopSending): overallResult.append(result.result); break". Of course, that will slow down every send, but probably not too much to make it practical. Have fun, Mike -- ________________________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com |