Making special method names, work with __getattr__

Antoon Pardon apardon at forel.vub.ac.be
Fri Apr 23 05:41:32 EDT 2010


The following is a proof of concept. The idea is to have variables that
represent symbolic names/expressions, you can work with like ordinary
values, but that can be evaluated later.

This is the code:

------------------------------------------------------------------------

import operator
from functools import partial

class Expression (object) :
  def __add__(self, term):
    return Binary(self, operator.__add__, term)

  def __getattr__(self, name):
    op = getattr(operator, name)
    return partial(Binary, self, op)

class Binary (Expression) :
  def __init__(self, left, op, right):
    self.left = left
    self.operator = op
    if not isinstance(right, Expression):
      right = Value(right)
    self.right = right

  def eval(self, dct):
    left = self.left.eval(dct)
    right = self.right.eval(dct)
    return self.operator(left, right)


class Symbol (Expression):
  def __init__(self, name):
    self.name = name

  def eval(self, dct={}):
    return dct[self.name]


class Value (Expression):
  def __init__(self, val):
    self.value = val

  def eval(self, dct={}):
    return self.value

def test():
  dct = {"var1" : 5, "var2" : 7}
  val1 = Symbol("var1")
  val2 = Symbol("var2")
  print val1.eval(dct)
  sum = val1 + 3
  print sum.eval(dct)
  sum = sum + val2
  print sum.eval(dct)
  product = val1 * 7
  print product.eval(dct)

test()

--------------------------------------------------------------------------

The result I get is:

5
8
15
Traceback (most recent call last):
  File "Symbolics", line 54, in <module>
    test()
  File "Symbolics", line 51, in test
    product = val1 * 7
TypeError: unsupported operand type(s) for *: 'Symbol' and 'int'

What I had hoped for was, that the line:
  
  product = val1 * 7

would be translated into something like

  product = val1.__mul__(7)

which would then be treated by the __getattr__ of the Expression superclass.

That doesn't seem to happen.


Does anyone have another idea, so I can get this to work without having
to manually add all numeric special methods to the Expression class.

-- 
Antoon Pardon



More information about the Python-list mailing list