Using eval with substitutions

Peter Otten __peter__ at web.de
Thu Aug 31 08:54:50 EDT 2006


abhishek at ocf.berkeley.edu wrote:

> Fredrik Lundh wrote:
>> (I'm afraid I don't really understand the point of your examples; what
>> is it you're really trying to do here ?)
> 
> A function is passed a bunch of string expressions like,
> x = "a+b"
> y=  "x*a"
> z= "x+y"
> 
> where a and b are assumed to have been assigned values in the local
> namespace. Now I have to evaluate another string such as,
> "z+y+x"
> 
> So as you say, I could do:
> x=eval(x), y=eval(y), z=eval(z) and finally eval("z+y+x") but the
> problem is that the initial strings are in no particular order, so I
> don't know the sequence in which to perform the first 3 evaluations. I
> was wondering if there was a simple way to 'pattern-match' so that the
> required substitutions like z->x+y->x+x*a->(a+b)+(a+b)*a could be done
> automatically.

Here is something to start with:

class EvalDict(object):
    def __init__(self, namespace):
        self.namespace = namespace
    def __getitem__(self, key):
        value = self.namespace[key]
        if isinstance(value, str):
            self.namespace[key] = value = eval(value, {}, self)
        return value

def smart_eval(expr, namespace):
    return eval(expr, {}, EvalDict(namespace))

def f():
    a = 2
    b = 3
    x = "a+b"
    y = "x*a"
    z = "x+y"

    return smart_eval("x + y + z", locals())

if __name__ == "__main__":
    print f()

Beware of infinite recursion:

# RuntimeError: maximum recursion depth exceeded
smart_eval("a + b", dict(a="b", b="a")) 

Peter



More information about the Python-list mailing list