I have a function main
that, given a string, should select one of many other functions, call it with some specific args
and kwargs
, and return its result. The most straightforward implementation of this is
def main(string):
if string == "a1":
return a(1)
elif string == "a2":
return a(2)
elif string == "b":
return b("foo", symbol=True)
# ...
elif string == "y":
return y()
assert string == "z", "Illegal string '{}'.".format(string)
return z("bar", 25)
but I don't like this unsightly huge conditional. More readable is perhaps
def main(string):
d = {
"a1": a(1),
"a2": a(2),
"b": b("foo", symbol=True),
# ...
"z": z("bar", 25),
}
return d[string]
This also eliminates possible typos where a key is elif
'd twice – nice.
Unfortunately, this initializes every entry in the dictionary just to throw away almost all of them right away. Defining d
outside of main
isn't a big improvement either in my case since main
is only executed a few times. Adding some lambda
s works
def main(string):
d = {
"a1": lambda: a(1),
"a2": lambda: a(2),
"b": lambda: b("foo", symbol=True),
# ...
"z": lambda: z("bar", 25),
}
return d[string]()
main("a")
but again, this makes the code less readable.
I'm wondering whether it's possible to define something like a dictionary iterator: With all key-value pairs specified, but the value only evaluated when picked. Perhaps there's a better idea.
Hints?