Skip to content

Instantly share code, notes, and snippets.

@bhyde
Last active June 28, 2017 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhyde/473ec596f3a094eea8c66f26f2329504 to your computer and use it in GitHub Desktop.
Save bhyde/473ec596f3a094eea8c66f26f2329504 to your computer and use it in GitHub Desktop.
Decorative dispatch table
class Dispatcher(object):
def __init__(self):
self.table = {}
def choice(self, key=None):
def decorator(fn):
self.table[key or fn.func_name] = fn
decorated_fn = fn
return decorated_fn
return decorator
def otherwise(self, *a, **b):
return self.choice('__otherwise__', *a, **b)
def case(self, key, *a, **b):
if key in self.table:
self.table[key](*a, **b)
else:
self.table['__otherwise__'](*a, **b)
d = Dispatcher()
@d.choice(key="hot")
def steamy(x, y=3):
print "so hot", x, y
@d.choice()
def cold(x, y=3):
print "cold", x, y
@d.otherwise()
def huh(x, y=-3):
print "huh?", x, y
d.case("cold", 1)
d.case("hot", 2)
d.case("tepid", 3, y=7)
class DictionaryWalker(Dispatcher):
def walk(self, parent):
other_fn = self.table.get('__otherwise__', None)
for key, child in parent.iteritems():
if key in self.table:
self.case(key, parent, key, child)
elif other_fn:
other_fn(parent, key, child)
dw = DictionaryWalker()
@dw.choice("left")
def walk_left(p, k, c):
print "left:", c
@dw.choice("right")
def walk_right(p, k, c):
print "right:", c
@dw.otherwise()
def huh2(p, k, c):
print "unexpected key", k, ":", c
dw.walk(dict(left="weak", head="big head", right="strong"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment