"casting" Python objects

Hans Nowak wurmy at earthlink.net
Wed May 22 19:56:33 EDT 2002


DJW wrote:

> In the main thread, I have a sub-class of jabber.Message, call it "FooMsg"
> (there are actually going to be multiple derived types of jabber.Message).
> My main application thread has a loop that pulls messages off the Queue and
> calls the appropriate handler inside of the message. However, the type of
> the messages are of type jabber.Message, not my FooMsg that contains the
> handlers:
> 
> class FooMsg( jabber.Message):
> 
>     def Handler( self ):
>         # call approriate handler for message
>         ...
> 
>  while 1:
>     msg = msg_queue.get()  # returns type jabber.Message
>     msg.Handler() # ERROR: Handler() is only in type FooMsg!!!
> 
> Obviously, one way around this is to only place FooMsgs in the Queue in the
> first place. But that seems to defeat the purpose of using a generic,
> reusable module like jabber.py. I want to use an unmodified version of
> jabber.py if at all possible. 

In order to be able to add FooMsg instances to the Queue,
do you really have to change jabber.py? I don't know these
objects, but if Queue accepts jabber.Message instances, then
it should also accept FooMsg instances, because they are
subclasses of jabber.Message. But maybe you cannot control
directly what goes in the queue...?

> The only other way I can figure to do this is
> something like:
> 
>  while 1:
>     msg = msg_queue.get()  # returns type jabber.Message
>     node = msg.asNode() # get the contents of the jabber message
>     foo_msg = FooMsg( node ) # create a new FooMsg with the message contents
>     foo_msg.Handler() # Now we are calling the correct type!
> 
> But this seems pretty ugly and inefficient. Is there something more Pythonic
> (ie, better) that I'm not seeing here? (also, I know that this is ugly OOP)

It doesn't seem so bad to me, but then again, I'm far from an OO
purist... :-)

Here's an alternative approach you might want to ponder. Instead
of subclassing jabber.Message, and creating an is-a relation,
why not use a has-a relation instead and use a class that *has*
a jabber.Message as an attribute? Like

  class MessageHandler:
      def __init__(self, jabbermsg):
          self.jabbermsg = jabbermsg
      def handler(self):
          # do something nice with self.jabbermsg...

In this light, code like

  while 1:
     msg = msg_queue.get()  # returns type jabber.Message
     node = msg.asNode() # get the contents of the jabber message
     handler = MessageHandler(node)
     handler.handler()

doesn't seem so "bad" anymore.

HTH,

-- 
Hans (base64.decodestring('d3VybXlAZWFydGhsaW5rLm5ldA==')) 
# decode for email address ;-)
The Pythonic Quarter:: http://www.awaretek.com/nowak/



More information about the Python-list mailing list