(See default security warning at end before you put code like this into production!)
The other answers do a good job of explaining the difference between exec
and eval
.
Nevertheless, I found myself wanting to take input like x=1; y=2; x+y
rather than force people to write:
def f():
x = 1
y = 2
return x + y
String manipulation of code to build this sort of function is a risky business.
I ended up using the following approach:
def multiline_eval(expr, context):
"Evaluate several lines of input, returning the result of the last line"
tree = ast.parse(expr)
eval_expr = ast.Expression(tree.body[-1].value)
exec_expr = ast.Module(tree.body[:-1])
exec(compile(exec_expr, 'file', 'exec'), context)
return eval(compile(eval_expr, 'file', 'eval'), context)
This parses python code; uses the ast library to rebuild an ast of everything apart from the last line; and the last line, execing the former and eval'ing the later.
Security warning
This is the obligatory security warning that you have to attach to eval
.
Eval
'ing and exec
'ing code that is provided by a non-privileged user is of course insecure. In these cases you may prefer to use another approach, or consider ast.literal_eval. eval
and and exec
tend to be bad ideas unless you actually want to give your user the full expressive power of python.