eval and dict

Andrew Dalke adalke at mindspring.com
Fri May 23 20:24:08 EDT 2003


Steffen Ries:
> I am trying to implement lazy evaluation of user provided expressions.
>
> I'm using "eval(expression, dictionary)" with multiple calls
> evaluating different expressions using the same context. It turned out
> that creating the dictionary up front is a performance bottleneck.
>
> Since I typically don't need all possible value in the dictionary, I
> was trying to defer creating the entries until an expression actually
> needs the entry.
>
> I tried to implement a delegating dictionary, but "eval(exp,
> lazyDict)" complains "TypeError: eval() argument 2 must be dict, not
> instance"

As others have pointed out, this is an implementation issues in
CPython which does not exist in Jython.  The CPython code is
done this way for performance.

This limitation is rather annoying, as both Alex Martelli and I have
wanted ways around it - in my case, for reasons very similar to
yours.  My solution was to use a real dict that starts empty, and
pass it to the eval.  Catch every KeyError in the eval, analyze
the message for the missing variable, and pull it from the lazy
dict into the real dict, and reevaluate the expression.

Ugly, but it works.

Alex and I had an exchange on c.l.py a few months ago on this.
I came up with another solution, which was to analyze the
byte code looking for top-level names.  This fixes a problem in
Alex's solution of looking at the co_names, but at the expense
of a lot more analysis and a dependence on CPython.

I've since come up with another option.  Use the compiler
package to build the parse tree, and extract the needed
names from that.  I think that's platform independent.

                    Andrew
                    dalke at dalkescientific.com






More information about the Python-list mailing list