Ways to dispatch (select) a function based on a string
Sometimes I want to select a function from a set of functions based on a string. The examples here are compiled from this, this and this stackoverflow post.
Option 1: dictionary
Probably the easiest, most straightforward method.
def func1():
print("Running func1")
def func2():
print("Running func2")
def func3():
print("Running func3")
= {
funcs "func1": func1,
"func2": func2,
"func3": func3,
}
def top_level_func(function="func1"):
= funcs[function]
f f()
Option 2: getattr
from module
Nice and clean due to import from external module (although that could easily be achieved for option 1, too)
mod.py
def func1():
print("Running func1")
def func2():
print("Running func2")
def func3():
print("Running func3")
import mod
def top_level_func(function="func1"):
= getattr(mod, function)
f f()
Option 3: using a decorator
Adapted from this post on stackoverflow.
class FunctionContainer:
def __init__(self):
self.funcs = {}
def _add(self, f):
self.funcs[f.__name__] = f
def add(self, f):
self._add(f)
return f
def __getitem__(self, function_name):
return self.funcs[function_name]
= FunctionContainer()
container
@container.add
def func1():
print("Running func1")
@container.add
def func2():
print("Running func2")
@container.add
def func3():
print("Running func3")
def top_level_func(function="func1"):
= container[function]
f f()
Other options
People also suggest to use eval
or globals()
for this case. Both are not ideal, due to the execution of arbitrary code or access to global variables in some way, which likely can be avoided in most cases.