8

So I have understood what exec and eval and also compile do. But why would I need to use them? I am being unclear on the usage scenario.

Can anyone give me some examples so that I can better appreciate the concept. Cause right I know it is all theory.

3
  • 3
    Fact: Things like eval are very rarely a valid choice, and only if the string fed to it is known to be secure. Commented Nov 11, 2010 at 18:55
  • 4
    Try searching for them in the Python source code files in the Python Standard Library. That is always an interesting place to start if you want to see basic Python features used well. Commented Nov 11, 2010 at 18:55
  • exec and eval can be quite useful in codegolfing. Commented Sep 30, 2017 at 14:36

8 Answers 8

5

I'll give an example in which I have used eval and where I think it was the best choice.

I was writing a simple software testing utility ... something to test whether student exercises were conforming to the assignment requirements. The goal was to provide a way for a simple configuration file to serve as a test specification (to get around a "chicken-and-egg" issue of using a programming language to describe/document/implement the test cases for elementary programming assignments).

I based my harness on the ConfigParser in the standard libraries. However, I did want the ability to represent arbitrary Python strings (including interpolations of \n, \t, and especially any interpolated hex encoded ASCII characters in the values read therefrom.

My solution was a try around an parsed_string=eval('''%s''' % cfg_read_item) followed by a try of the triple double-quoted version ("""%s""") of the same.

This is a case where the alternative would have been to write (or find a pre-written) Python language parser and figure out how to include and adapt it to my program. The risks are minimal (I'm not worried that student submitted code is going to trick my parser, break out if its jail, delete all my files, send my credit card numbers to Romania and so on)*

*(In part because I was testing them under Linux from an untrusted headless user account).

As here others have said, there are other use cases where you're building code from a template based on input data and need to execute that code (meta programming). You should always be able to accomplish those tasks in another way. However, whenever that alternative entails coding effort that approaches writing a general programming language parser/compiler/interpreter .... then eval may be the better approach.

Sign up to request clarification or add additional context in comments.

Comments

4

The standard library has an instructive example of how to use exec. collections.namedtuple uses it to build a class dynamically.

template = '''class %(typename)s(tuple): '%(typename)s(%(argtxt)s)' \n __slots__ = () \n _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' return _tuple.__new__(_cls, (%(argtxt)s)) \n ...''' namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, OrderedDict=OrderedDict, _property=property, _tuple=tuple) try: exec template in namespace except SyntaxError, e: raise SyntaxError(e.message + ':\n' + template) 

3 Comments

@dan_waterworth: oops, sorry for deleting my comment (I hadn't seen yours). Yes, I agree it's possible.
@dan_waterworth: I wish I knew the reason why Raymond Hettinger chose to implement this with exec instead of a metaclass.
@unutbu In a 2008 issue that I just ran across where someone offered a non-eval version, Raymond and another developer weigh in on the problems with the early experiments in non-eval named tuples: bugs.python.org/issue3974
3

ast uses compile to generate abstract syntax trees from Python source code. These are used by modules such as pyflakes to parse and validate Python.

def parse(expr, filename='<unknown>', mode='exec'): """ Parse an expression into an AST node. Equivalent to compile(expr, filename, mode, PyCF_ONLY_AST). """ return compile(expr, filename, mode, PyCF_ONLY_AST) 

Comments

2

You don't need to use them, and in my opinion you should avoid them.

They are only useful in cases where you are generating the code itself, which in the end is going to most likely be considered bad practice.

If you are considering using eval() for things like mathematical expressions, you would be better sanitizing the input before evaluating it. You never know what kind of 'text' the user sends in that might screw up the application itself.

5 Comments

Having "meta-programming" equal to "bad practice" is a bit harsh, IMHO. A meta-programming, while sometimes more complex and more error-prone, can yield a better (i.e. faster or more maintainable) code when used properly.
Meta-programming is not bad pratice. It can be very beautful.
Every tool and method has its domain of application. But you are right, domain of application of meta-programming at all is very narrow.
@Paulo - beautiful should never be the reason to write good and clear code. @Kos - I was referring mostly to exec and compile... As the author of the question mentioned, I have never seen good use cases where they could not be rewritten in simpler or less elaborate ways. In addition meta-programming can be achieved without using those 3 keywords
A different way to say this might be "If you need to ask, then you should probably avoid them." Although you can sometimes get very elegant solutions to problems, more often such solutions are difficult to understand, difficult to extend, and difficult to debug.
1

I think I have a valid use. I am using Python 3.2.1 inside Blender 2.6.4 to modify a set of points with x,y coordinates (in the z-plane).

The goal is to add concentric rings of new points around each existing point, with the rings behaving as ripples, (like when you drop a stone in a pond). The catch is that I want the ripples to constructively/destructively interfere with one another, so first I'm going through and constructing a 'ripple equation' centered at each point, and summing all the ripple equations together into one gigantic mathematical equation, which I will then feed the original points into in order to generate the correct z-value to assign each one to.

My plan is to append each additional term in the equation to the previous as a string, and then use eval() to calculate the z-value for the new set of points.

Comments

0

Are you just asking for an example? You could write a simple app that reads from standard in and allows the user to input various expressions, like (4*2)/8 - 1. In other languages (Java, C++, etc.) this would be close to impossible to evaluate, but in python it is simple, just:

eval((4*2)/8 - 1) 

That being said, unless you are careful, using these things can be very dangerous as they (essentially)allow the user a huge amount of access.

2 Comments

Not "close to impossible to evaluate" --- Python itself is written mostly in C and Python can evaluate such expressions. Better to say that evaluation of expressions would entail about as much work as writing a programming language parser and compiler or interpreter.
@Jim Dennis. Agreed that it's not "close to impossible". It's doable given a couple hours, maybe even less. But it is a pain.
0

This is used in meta-programming (when the program writes itself). For example, you have animals of different species, which are described with different classes: Lion, Tiger, Horse, Donkey. And you want to simulate crossbreeding between them, for exampe, between Lion and Tiger. When you write the program, you can not determine how the user will cross the animals, but you can create new classes of animals on the fly:

new_class_name = boy.class.to_str() + girl.class.to_str() eval("class " + new_class_name + " extends " + boy.class.to_str() + ", " + girl.class.to_str()) 

P. S. Sorry, I forgot Python some. So there is a bunch of pseudo-code.

1 Comment

No, this is not a valid use of eval -- you should use type instead.
0

Here's a valid use case. In the python paste middleware (for web programming) when an exception is raised it creates a command line within the browser. This works be using methods like these. Also, in Blender there is an option to animate values using python expressions and this works using eval.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.