The Python version of the C-style switch statement is either a bunch of if/else's or a dictionary. Going the dictionary route can be ugly looking (not to mention confusing, pulling a value out of a mapping and calling it). This just encapsulates the whole thing and adds some support for a pseudo-default case.
The structure is a bit weird, nowhere near as nice as regular syntax, but if you absolutely have to do this, it makes it easier to read.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""A simple function (roughly) implementing C-style switch statements. | |
Usage:: | |
switch(value, { | |
'it': | |
"You said the word!", | |
'fruit': | |
"Suppose he's got a pointed stick.", | |
'camelot': | |
"'Tis a silly place.", | |
Ellipsis: | |
("You've got two empty halves of coconut and you're " + | |
"bangin' 'em together.") | |
}) | |
Also accepts *args and **kwargs, which will get passed on to the | |
specified case if it is callable. | |
The result of the callable is returned, as is the value of | |
non-callables. | |
Since `default` isn't a built-in name (and obviously not a statement), | |
the under-used built-in singleton Ellipsis is used in its place under | |
the assumption that it is unlikely to be used as a real case. | |
Fortunately, in the event that it *is* used as a real case, using | |
Ellipsis as the switch value will properly select the Ellipsis case. | |
Unfortunately, so will a non-match. It's probably best you don't use | |
Ellipse as a real case. | |
Finally: implicit break, no fall-through at all. Ever. First of all, | |
dict isn't ordered, so fall-through would be weird. Second, I'm not | |
going to specialize for OrderedDict (plus it would look weird on your | |
end), and third, I have no idea how to put breaking in if I did. If you | |
want this, do it yourself. | |
""" | |
def switch(value, cases, *args, **kwargs): | |
try: | |
case = cases[value] | |
except TypeError: | |
raise TypeError("Cases must be scriptable.") | |
except KeyError: | |
case = cases[Ellipsis] if Ellipsis in cases else None | |
finally: | |
try: | |
return case(*args, **kwargs) | |
except TypeError: | |
return case | |
def main(): | |
import sys | |
try: | |
value = sys.argv[1] | |
except IndexError: | |
value = None | |
print switch(value, { | |
'it': | |
"You said the word!", | |
'fruit': | |
"Suppose he's got a pointed stick.", | |
'camelot': | |
"'Tis a silly place.", | |
Ellipsis: | |
("You've got two empty halves of coconut and you're " + | |
"bangin' 'em together.") | |
}) | |
if __name__ == "__main__": | |
main() |