You can make your dispatch tables easier to maintain by using a decorator to assign a key to each method you wish to save in the dictionary for the dispatch table.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | class RPN_Evaluator(object):
  def __init__(self):
    self.stack = []
  def push(self, x):
    self.stack.append(x)
  def pop(self):
    return self.stack.pop() if self.stack else 0
  def result(self):
    return self.stack[:]
  operations = {}
  assign = lambda d, k: lambda f: d.setdefault(k, f)
  @assign(operations, '+')
  def plus(self, a, b):
    return a + b
  @assign(operations, '-')
  def minus(self, a, b):
    return a - b
  @assign(operations, '*')
  def mult(self, a, b):
    return a * b
  @assign(operations, '/')
  def div(self, a, b):
    return a / b
  def dispatch(self, k, *args, **kwds):
    try:
      method = self.operations[k].__get__(self, type(self))
    except KeyError:
      assert k in self.operations, "invalid operation: " + repr(k)
    return method(*args, **kwds)
  def eval(self, rpn):
    for x in str(rpn).split():
      try:
        value = int(x)
      except ValueError:
        b = self.pop()
        a = self.pop()
        value = self.dispatch(x, a, b)
      self.push(value)
    return self.result()
calc = RPN_Evaluator()
calc.eval('2 2 +')
calc.eval('1 2 3 4 * * *')
calc.eval('1 2 + 3 4 + 5 + +')
calc.eval('5 5 1 + * 2 /')
print calc.result()   # [4, 24, 15, 15]
 | 
When you have a dispatch table with a very large number of methods, it's nice to have the key value right next to the method.
As of Python 2.2, you may use the __get__ method of a function to turn it into a bound method.
    Tags: shortcuts
  
  
      
 Download
Download Copy to clipboard
Copy to clipboard