[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