[Tutor] What are *appropriate* uses for exec() and eval() ?

Steven D'Aprano steve at pearwood.info
Tue Feb 17 16:31:06 CET 2015


On Mon, Feb 16, 2015 at 07:10:21PM -0800, Devin Jeanpierre wrote:
> On Mon, Feb 16, 2015 at 6:15 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> > Here is a fork of that recipe. It uses an inner class for the new
> > namedtuple class. The only thing which needs exec is the __new__ method.
> >
> > http://code.activestate.com/recipes/578918-yet-another-namedtuple/
> >
> > This demonstrates a powerful truth about Python: *most of the time* you
> > don't need to use exec or eval because the standard language features
> > are powerful enough to solve the problem for you. Using a dynamically
> > created inner class is *almost* enough to solve this problem, only the
> > __new__ method defeats it. If our requirements where just a little less
> > demanding, we could avoid exec completely.
> 
> No, exec is not necessary at all. 

I'm not sure that I said that exec was "necessary" anywhere, but since 
you mention it, how about the two earlier examples I gave, timeit and 
doctest? Especially doctest. How would you implement doctests without 
exec?

Of course you could write your own Python parser, and build your own 
Python interpreter. But that's just re-inventing exec. And it would be 
horribly slow. Back in the very early days of PyPy, they wrote a Python 
interpreter using nothing but pure Python. It was about 100 times slower 
than the regular Python interpreter.

Another reasonable use for exec is to develop your own language or 
mini-language. You generate Python code, compile it, then execute it. 
Template engines like Mako, Jinja2 and Genshi work like this, or so I am 
lead to believe.



> If they had to the author could have
> reimplemented the argument assignment logic by hand. They chose not to
> because it is "too hard". (And it is.)  Fortunately, they don't have
> to go that far:
> 
> signature = inspect.Signature([
>     inspect.Parameter(field_name, inspect.Parameter.POSITIONAL_OR_KEYWORD)
>     for field_name in field_names])

Hmmm. Well, namedtuple was added to Python in version 2.6.

[steve at ando ~]$ python2.6
Python 2.6.7 (r267:88850, Mar 10 2012, 12:32:58)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-51)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
py> from inspect import Signature
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name Signature

So much for that idea.

Of course you are right that using exec is rarely the *only possible* 
way to solve a problem. But it's a tool like any other tool, we 
shouldn't be afraid to use it when it is the best tool for the job. The 
problem comes from people using it when it is the *wrong* tool for the 
job, or using it carelessly.



-- 
Steve


More information about the Tutor mailing list