The case against Python

Posted on April 19, 2016

Or, how to implement a switch statement in Python. Because why not.

Using closures and the decorator syntax, we can make something that looks reasonably close to a simple switch statement in Python. The idea is this: we’ll design a simple factory function to generate both a case function that can be used as a decorator to register cases in our switch and a run function to run our switch statement.

def switch(expr):
    cases = []

    def case(e):
        def wrapper(f):
            cases.append(e, f)
        return wrapper

    def run():
        v = expr()
        for e, body in cases:
            if e == v:
                body()
                break

    return case, run

We require that the parameter to switch be a callable so that we can delay evaluating the expression to switch on until the moment the switch is run. In fact, we might even want to have the generated run take the expression to switch on as a parameter, so that we can reuse the same switch many times on different values.

Let’s see our switch statement in action.

if __name__ == '__main__':
    x = input()
    case, run = switch(lambda: x)
    
    @case(5)
    def _():
        print 'kindergarden!'

    @case(18)
    def _():
        print 'university!'

    run()

This trick of using decorators for side effects rather than to perform a transformation of a function is extremely useful. It’s how the Flask framework registers handlers on routes, for example.

There are some simple improvements that can be made to this.