Advertisement
Guest User

Untitled

a guest
Feb 21st, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.11 KB | None | 0 0
  1. from collections import OrderedDict, namedtuple
  2. from functools import partial
  3.  
  4. class Dispatcher(object):
  5. def __init__(self):
  6. self.handlers = OrderedDict()
  7.  
  8. def match(self, *args):
  9. def match_inner(handler_fn):
  10. self.handlers[args] = handler_fn
  11. return self
  12.  
  13. return match_inner
  14.  
  15. def on(self, *args):
  16. def on_inner(handler_fn):
  17. # We need an outer closure here as a reference to `a`
  18. # in a single closure would reference the last value of
  19. # `a` after the for loop.
  20. matchfn = lambda a: lambda v: isinstance(v, a)
  21. matches = [matchfn(a) for a in args]
  22. return self.match(*matches)(handler_fn)
  23.  
  24. return on_inner
  25.  
  26. def __call__(self, *args, **kwargs):
  27. if len(args) == 0:
  28. raise ValueError('No arguments to match on')
  29.  
  30. for matches, handler in self.handlers.iteritems():
  31. if any(m(args[-1]) for m in matches):
  32. return handler(*args, **kwargs)
  33.  
  34. raise ValueError('No handlers found for value {}'.format(args[-1]))
  35.  
  36. def __get__(self, obj, objtype):
  37. return partial(self.__call__, obj)
  38.  
  39.  
  40. # Simple example:
  41.  
  42. foo = Dispatcher()
  43.  
  44. @foo.on(int, float)
  45. def foo(x):
  46. return "Got a number! {}".format(x)
  47.  
  48. @foo.on(str, unicode)
  49. def foo(x):
  50. return "Got some text! {}".format(x)
  51.  
  52. @foo.on(dict)
  53. def foo(x):
  54. return "Wow a dict {}".format(x)
  55.  
  56. print(foo(1))
  57. print(foo(1.0))
  58. print(foo('abc'))
  59. print(foo(u'def'))
  60. print(foo({}))
  61.  
  62.  
  63. # Class Example:
  64.  
  65.  
  66. Leaf = namedtuple('Leaf', 'l r')
  67. tree = Leaf(Leaf(Leaf(1, 2), Leaf("3", 4.0)), [5])
  68.  
  69. class TreeVisitor(object):
  70.  
  71. visit = Dispatcher()
  72.  
  73. @visit.on(Leaf)
  74. def visit(self, value):
  75. return self.visit(value.l) + ' || ' + self.visit(value.r)
  76.  
  77. @visit.on(int)
  78. def visit(self, value):
  79. return 'i' + str(value)
  80.  
  81. @visit.on(str)
  82. def visit(self, value):
  83. return 's"' + value + '"'
  84.  
  85. @visit.on(float)
  86. def visit(self, value):
  87. return 'f' + str(value)
  88.  
  89. @visit.on(list)
  90. def visit(self, value):
  91. return str(value)
  92.  
  93. print(TreeVisitor().visit(tree))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement