|
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
|