Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of exec and eval in Python

Tags:

python

eval

exec

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.

like image 571
user225312 Avatar asked Nov 11 '10 18:11

user225312


People also ask

What is eval and exec in Python?

Basically, eval is used to evaluate a single dynamically generated Python expression, and exec is used to execute dynamically generated Python code only for its side effects.

What is exec and eval?

Eval() only evaluates the single expression, not the complex logic code, whereas Exec can be used to execute any number of expression. exec() accept the source code which contains statements like, for, while, print, import, class, if we pass these statement to eval() it will throw error.

What is the use of exec in Python?

Exec function can dynamically execute code of python programs. The code can be passed in as string or object code to this function. The object code is executed as is while the string is first parsed and checked for any syntax error. If no syntax error, then the parsed string is executed as a python statement.

What is eval in Python used for?

Python's eval() allows you to evaluate arbitrary Python expressions from a string-based or compiled-code-based input. This function can be handy when you're trying to dynamically evaluate Python expressions from any input that comes as a string or a compiled code object.


5 Answers

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.

like image 136
Jim Dennis Avatar answered Sep 23 '22 21:09

Jim Dennis


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)
like image 35
unutbu Avatar answered Sep 23 '22 21:09

unutbu


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)
like image 26
Katriel Avatar answered Sep 23 '22 21:09

Katriel


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.

like image 39
unode Avatar answered Sep 21 '22 21:09

unode


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.

like image 45
Cody Avatar answered Sep 24 '22 21:09

Cody