[Tutor] avoid eval how???

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Thu Nov 3 20:13:45 CET 2005


On Thu, 3 Nov 2005, Pujo Aji wrote:

> I have a dynamic functions which created by some algorithms during
> runtime. These functions are in string type. When I want to use it, I
> can use eval command. But can someone give me more suggestion about how
> to handle this problem, I want to avoid eval.


Hi Pujo,

To do this safely, many programmers will take a parsing + evaluation
approach.

A parser can take a string, such as:

    "x + sin(x)"

and turn it into a data structure that can be evaluated safely.


As a concrete example of what it means to use data structures to represent
these dynamic functions:

##############################################
class Add:
    """Represents the addition operator."""
    def __init__(self, lhs, rhs):
        self.lhs, self.rhs = lhs, rhs

    def evaluate(self, environment):
        lval = self.lhs.evaluate(environment)
        rval = self.rhs.evaluate(environment)
        return lval + rval

class Variable:
    """Represents a variable name."""
    def __init__(self, id):
        self.id = id

    def evaluate(self, environment):
        return environment[self.id]
##############################################

Let's say that we have a string like:

    "x + y"

We can capture the essence of the meaning there by building the data
structure:

    Add(Variable('x'), Variable('y'))

The job of doing the string-to-data-structure thing is pretty automated if
we use parser tools like pyparsing.  I won't go into parsing at the
moment; I'll treat that as a separate topic, but if you want to explore
parsers, see:

    http://pyparsing.sourceforge.net/


Once we have a dynamic function in a data structure format like this, then
things aren't so bad.  We can "evaluate" that data structure at multiple
points:

######
>>> equation = Add(Variable('x'), Variable('y'))
>>> equation
<__main__.Add instance at 0x403a7e2c>
>>> equation.evaluate(dict(x=3, y=4))
7
>>> equation.evaluate(dict(x=19, y=42))
61
>>>
>>> another = Add(Variable('x'), Add(Variable('y'), Variable('z')))
>>> another.evaluate(dict(x=3, y=4, z=5))
12
######

Does this make sense?  We can talk about this in more detail if you'd
like.



More information about the Tutor mailing list