2

Python's built-in compile function has eval, exec and single modes. single mode seems a bit useless (ref). How about the eval and exec?

  • eval: works on an expression
  • exec: works on statements

But an expression is a statement. My question is: why not just use exec all the time?

PS: I've read some related questions like Python built-in function "compile". What is it used for?. They do a good job explaining the difference between the modes, but doesn't directly answer my question.

F.S.
  • 1,175
  • 2
  • 14
  • 34
  • 1
    ``single`` is what drives the REPL, so any source that implies it's useless or "cannot think of a good use" for it should be approached with care. – MisterMiyagi Aug 26 '21 at 19:05

3 Answers3

4

Just like the eval builtin, the compile eval mode creates a code object that evaluates an expression and returns its result. In contrast, exec mode does not return a result.

>>> exec_code = compile("1 + 2", "<stack overflow>", "exec")
>>> eval(exec_code)  # no result for "exec" mode code
>>> eval_code = compile("1 + 2", "<stack overflow>", "eval")
>>> eval(eval_code)  # some result for "eval" mode code
3

But an expression is a statement.

This is not true. An expression evaluates to a value, a statement does not.

While expression statements mean an expression can be used "as a" statement, that does not make the two equivalent. An expression statement contains an expression; when run, the statement evaluates the expression but discards the result.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
  • I see. I have a block of code that I need to `eval` and get its result. The code is too complex to be fit into one expression. Is it even possible? – F.S. Aug 26 '21 at 19:38
  • @F.S. Since a block of code cannot have a result, it's by definition not possible. The closest thing is to ``exec`` the code with an explicit global namespace, and fetch all data of interest from that namespace – but it requires the code to actually write that data to the namespace. – MisterMiyagi Aug 26 '21 at 19:50
4

An expression is not a statement, but there is a kind of statement (the expression statement) that consists of a single expression. This nifty bit of indirection allows the parser to think a Python module as a sequence of statements, rather than a sequence of statements and/or expressions.

An expression has a value; an expression statement does not: it simply evaluates the expression (primarily for its side effects) and discards the value.

eval returns the value of the evaluated expression.

exec will execute an expression as an expression statement, but discard the value of the expression. (exec itself is a function which is primarily called in expression statements, rather than as part of a larger expression.)

chepner
  • 497,756
  • 71
  • 530
  • 681
0

updated and extra examples.

The accepted answer's examples do not working in python 3.10 any more.

>> exec_code = eval(compile("1 + 2", "<stack overflow>", "exec"))
>>> eval(exec_code)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: eval() arg 1 must be a string, bytes or code object

Updated examples for python 3.10

>> exec_code = compile("1 + 2", "<stack overflow>", "exec")
>>> exec(exec_code)
>>> eval_code = compile("1 + 2", "<stack overflow>", "eval")
>>> eval(eval_code)  # some result for "eval" mode code
3

Example of a block of code

>>> a='''
... b=1+4
... print(b)
... '''
>>> exec_code = compile(a, "<stack overflow>", "exec")
>>> exec(exec_code)
5
oldpride
  • 761
  • 7
  • 15