Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from collections import OrderedDict, namedtuple
- from functools import partial
- class Dispatcher(object):
- def __init__(self):
- self.handlers = OrderedDict()
- def match(self, *args):
- def match_inner(handler_fn):
- self.handlers[args] = handler_fn
- return self
- return match_inner
- def on(self, *args):
- def on_inner(handler_fn):
- # We need an outer closure here as a reference to `a`
- # in a single closure would reference the last value of
- # `a` after the for loop.
- matchfn = lambda a: lambda v: isinstance(v, a)
- matches = [matchfn(a) for a in args]
- return self.match(*matches)(handler_fn)
- return on_inner
- def __call__(self, *args, **kwargs):
- if len(args) == 0:
- raise ValueError('No arguments to match on')
- for matches, handler in self.handlers.iteritems():
- if any(m(args[-1]) for m in matches):
- return handler(*args, **kwargs)
- raise ValueError('No handlers found for value {}'.format(args[-1]))
- def __get__(self, obj, objtype):
- return partial(self.__call__, obj)
- # Simple example:
- foo = Dispatcher()
- @foo.on(int, float)
- def foo(x):
- return "Got a number! {}".format(x)
- @foo.on(str, unicode)
- def foo(x):
- return "Got some text! {}".format(x)
- @foo.on(dict)
- def foo(x):
- return "Wow a dict {}".format(x)
- print(foo(1))
- print(foo(1.0))
- print(foo('abc'))
- print(foo(u'def'))
- print(foo({}))
- # Class Example:
- Leaf = namedtuple('Leaf', 'l r')
- tree = Leaf(Leaf(Leaf(1, 2), Leaf("3", 4.0)), [5])
- class TreeVisitor(object):
- visit = Dispatcher()
- @visit.on(Leaf)
- def visit(self, value):
- return self.visit(value.l) + ' || ' + self.visit(value.r)
- @visit.on(int)
- def visit(self, value):
- return 'i' + str(value)
- @visit.on(str)
- def visit(self, value):
- return 's"' + value + '"'
- @visit.on(float)
- def visit(self, value):
- return 'f' + str(value)
- @visit.on(list)
- def visit(self, value):
- return str(value)
- print(TreeVisitor().visit(tree))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement