eval and dict

Alex Martelli aleaxit at yahoo.com
Fri May 23 10:27:17 EDT 2003


Steffen Ries wrote:

> Hi,
> 
> 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.

Not quite what you want (since and / or operators might well result in
expressions not NEEDING a variable even though the expression MENTIONS
the variable...), but the code-object you obtain by compiling the
expression does contain a list of the names it accesses:

>>> expr = 'a+b*c'
>>> cexp = compile(expr, '<string>', 'eval')
>>> cexp.co_names
('a', 'b', 'c')

This may be a bid wider than you want because it doesn't single out
"toplevel" names:

>>> expr = 'a+b.c'
>>> cexp = compile(expr, '<string>', 'eval')
>>> cexp.co_names
('a', 'b', 'c')

i.e. name 'c' is there even though it's used as the name of an attribute
within object 'b' only.  Despite this slight disadvantage I've found that
co_names lets me be lazy enough for my own needs.

> Is there a way to bypass this behavior of eval()?

Not that I know of -- I believe it optimizes by cally PyDict_... methods
directly.  Yes, it WOULD be nice to avoid this, since eval's performance
is hardly the bottleneck in most use cases, but I believe it just falls
out of reusing the same mechanisms as for the normal interpreter.  Still,
a patch fixing this without slowing general Python ops down would sure
be nice to have (hint, hint...).


Alex





More information about the Python-list mailing list