opt = {0: do_a,
1: do_b,
3: do_b,
4: do_c}
opt[option]() opt = {0: do_a,
1: do_b,
3: do_b,
4: do_c}
opt[option]()It's one of the examples in Forth. Plan 9 uses that technique in C a lot too.
This example is ramfs which creates an in memory file system (that you can mount in Unix btw, in 166 LoC)
http://swtch.com/usr/local/plan9/src/lib9p/ramfs.c
fsopen, fsread, fswrite, fscreate are C functions declared in the same source file :
Srv fs = {
.open= fsopen,
.read= fsread,
.write= fswrite,
.create= fscreate,
};
fs is then passed to a library which calls them as needed.Edit: Looked it up, dispatch table is in Wikipedia:
And it's something I do on occasion. For example:
https://github.com/ubernostrum/webcolors/blob/master/webcolo...
s = {'square': lambda x: x **2, 'simple': lambda x: x, 'cube': lambda x: x ** 3}
s.get('square', lambda x: 0)(10)
s.get('nonexistent', lambda x: 0)(10)
Substitute lambdas for real functions and you have a powerful switch case.If your dict keys are just numbers, then no, probably not. But strings mapping to functions, and in some cases objects and other things, are often used to substitute for numerous if and elif statements.
I'd love to hear why you think it's not ideal.
I'm not the poster you posed that question to. But for me, the one big drawback of using that idiom is that the function signatures have to be identical. So you either have to resort to args/kwargs, or you have an additional intermediary method between the actual "guts" of what you're calling, and the "switch" statement.
Or you live with the fact that you're passing unused/unnecessary parameters to your functions.
Having said that, just because I consider something more Pythonic doesn't mean I prefer it. I've worked in a lot of languages over the years and still work in several in addition to Python. I really enjoy Python, but I prefer techniques that are more universal in many cases. For example, I prefer the idiom of looping over a list index to using Python's "enumerate" in most cases, because index looping is a common cross-language idiom and enumerate usually doesn't offer any benefit I value more than universal obviousness.
Other things such as Python's `for item in items` looping style are both VERY Pythonic and much nicer than, say, index looping, so I would almost always prefer such idioms.
The above switch -> function pointerish thing is clear to me from years of C/C++, but it is both less generally applicable across languages than if-elif... and less Pythonic, so I would prefer the if-elif... approach.
Obviously a matter of preferences, but since you asked....
I sometimes see this in code and think to myself, whoever wrote this needs to learn themselves some idiomatic python :) I don't think there's much point trying to force stuff that makes sense in one language into another language. Play to a languages strengths and all that.
I think you're right about if-elif generally being more powerful than the jump table. Though the jump table is useful in that you can define it in one place and use it in another.
func = getattr(self, 'do_%s' % thing)
func(args)
I've seen in some codebases :)