What's the difference between eval, exec, and compile?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
eval, exec, and compile all deal with dynamic Python code, but they solve different problems. eval evaluates a single expression and returns a value, exec runs Python statements for their side effects, and compile turns source text into a reusable code object.
They are related, but not interchangeable. If you mix them up, you usually get syntax errors, missing return values, or code that is much harder to reason about than it needs to be.
Use eval for expressions that return a value
eval accepts a Python expression, not a block of statements. Because an expression produces a value, eval returns that value.
It also works with a provided variable scope:
What eval cannot do is run statements such as assignments, loops, or function definitions:
That is because x = 10 is a statement, not an expression.
Use exec for statements and code blocks
exec runs Python code for its effects. It does not return the result of the last line.
This makes exec suitable for dynamic function definitions, assignments, imports, or multi-line code blocks.
Because exec is statement-oriented, it is more flexible than eval, but it is also harder to contain safely.
Use compile when you want to parse once and run later
compile does not execute code by itself. It converts source code into a code object that can later be passed to eval or exec.
For statements:
This is useful when the same source is executed many times. You compile once, then reuse the code object instead of reparsing the string repeatedly.
The mode argument matters:
- '
"eval"expects a single expression' - '
"exec"expects statements or a code block' - '
"single"is mainly for interactive-style input'
Choose the right tool
A good rule is:
- if you need a value from one expression, use
eval - if you need side effects from statements, use
exec - if you need reusable compiled code, use
compile
Often, though, the best answer is "use none of them." If you can call a function, parse JSON, or use a normal dispatch table, that is usually clearer and safer than running dynamically generated Python code.
Common Pitfalls
- Running untrusted input through
evalorexecand assuming restricted namespaces make it safe. - Using
evalfor statements such as assignments or loops and then being surprised by a syntax error. - Expecting
execto return the result of the last expression when it only performs side effects. - Calling
compilewithout a real reuse or tooling need and adding unnecessary complexity. - Reaching for dynamic execution when a normal function call, parser, or dispatch table would be clearer.
Summary
- '
evalruns a single expression and returns its value.' - '
execruns statements and code blocks for their side effects.' - '
compileturns source text into a code object for later execution.' - The
modepassed tocompilemust match the kind of source you are compiling. - '
evalandexecare dangerous with untrusted input and should be avoided unless dynamic execution is truly necessary.'

