This post originated from an RSS feed registered with Python Buzz
by Thomas Guest.
Original Post: Lexical Dispatch in Python
Feed Title: Word Aligned: Category Python
Feed URL: http://feeds.feedburner.com/WordAlignedCategoryPython
Feed Description: Dynamic languages in general. Python in particular. The adventures of a space sensitive programmer.
A recent article on Ikke’s blog shows how to emulate a C switch statement using Python. (I’ve adapted the code slightly for the purposes of this note).
Here the cases dict maps strings to functions and the “switch” is a simple matter of looking up and dispatching to the correct function. This is good idiomatic Python code. When run, it outputs:
one
two
three
unknown
Here’s an alternative technique which I’ve sometimes found useful. Rather than build an explicit cases dict, we can just use one of the dicts lurking behind the scenes — in this case the one supplied by the built-in globals() function.
Leaving the handle_*() functions as before, we could write:
for i in 'one', 'two', 'three', 'four':
handler = globals().get('handle_%s' % i, handle_default)
print handler()
Here, globals() returns us a dict which maps names in the current scope to their values, and since our handler functions are uniformly named, we can combine some string formatting with a simple dictionary look-up to get the required function.
A warning: this is unusual and non-idiomatic code, and in this particular case, the original explicit dictionary dispatch would be better. In other situations though, when the scope narrows to a class or a module, it may well be worth remembering that classes and modules behave like dicts which map names to values. The built-in getattr() function can then be used as a function dispatcher. Here’s a class-based example:
Maybe not the most fully-formed of classes, but I hope you get the idea! Incidentally, append() returns a reference to self so clients can chain calls together.
>>> print Paragraph().append("Word Aligned", BOLD
... ).append(" is at "
... ).append("http://wordaligned.org", LINK)
<p><b>Word Aligned</b> is at <a href="http://wordaligned.org">http://wordaligned.org</a></p>