Writing multiple if-else
statement clauses as a switch-style case can be
a hassle to maintain, especially if you're working with dynamic switches.
With no specific case
or switch
implementation in python's standard library,
I've liked using dispatch tables.
A dispatch table can be defined as a mapping of pointers to functions.
Let's review a simple example.
A simple if-else
statement set would look like the following (assuming the run_*
functions are available)
class IfElse:
def run(self, version: str, data: bytes):
if version.startswith("alpha"):
return run_alpha(data)
elif version.startswith("beta"):
return run_beta(data)
elif version.startswith("gamma"):
return run_gamma(data)
elif version.startswith("delta"):
return run_delta(data)
But with a dispatch table we can turn that into:
class DispatchTable:
table = {
"alpha": run_alpha,
"beta": run_beta,
"gamma": run_gamma,
"delta": run_delta
}
def run(self, version: str, data: bytes):
return self.table[version](data)
What's great about dispatch tables is that we have added a new element of key definition.
We can dynamically define these keys based on whatever we want and append those to the data-structure on whatever conditions and operations we need to support in our code.
In my opinion, this kind of approach is much more desirable for a couple important reasons.
The dispatch mechanism doesn’t need to know anything specific about our function handlers.
This also converts a linear time lookup to a constant time lookup. Dictionaries are hash tables in python, so the look-up process takes a constant time, while the if-elif
statement set needs a linear scan across the whole set of statements (this could get problematic if you're dynamically writing statements that could span thousands of cases 🤖).