How do I execute a string containing Python code in Python?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Python can execute code stored in a string, but that capability should be treated as a sharp tool. The language gives you exec for statements and eval for expressions, yet both functions can execute arbitrary code if you pass untrusted input. In practice, the hardest part of this task is not the syntax. It is deciding whether code execution is really the right solution.
Use eval Only for Simple Expressions
eval evaluates a single Python expression and returns its result.
Output:
This is limited to expressions, not statements. You cannot define functions, run loops, or assign variables with eval. That limitation is useful because it narrows the surface area slightly, but it does not make eval safe for untrusted input.
Use exec for Statements or Multi-Line Code
If the string contains assignments, function definitions, or multiple lines, use exec.
Output:
exec returns None, so if you need a result you usually place it in a namespace dictionary and read it back afterward. Passing an explicit dictionary makes the data flow easier to inspect than letting executed code mutate your module globals.
Control the Namespace Explicitly
Both exec and eval accept global and local namespace dictionaries. That lets you constrain what names are visible during execution.
This prevents direct access to normal built-ins, but it is not a full security boundary. Python execution is flexible enough that sandboxing with bare dictionaries is not reliable against malicious input. Namespace control is useful for predictability, not for true isolation.
Prefer Safer Alternatives When You Can
Many uses of eval and exec are really parsing problems in disguise. If the string is data, parse it as data. If it is a configuration, use a configuration format. If it is a mathematical expression, use a constrained parser.
For example, if the input is meant to be a Python literal such as a list or dictionary, ast.literal_eval is far safer than eval.
literal_eval can handle strings, numbers, tuples, lists, dictionaries, booleans, and None, but not arbitrary executable code. That is exactly why it is often the better answer.
Compile Once for Repeated Execution
If the same dynamic code will run many times, compile it once and then execute the compiled object. That separates parsing from execution and avoids repeated compilation overhead.
This is useful in rule engines or plugin-like systems where the input is trusted and reused.
Decide Whether Dynamic Execution Is Justified
Good reasons to execute a string are relatively rare:
- A trusted plugin system.
- Interactive educational tooling.
- Controlled expression evaluation in internal tools.
Weak reasons include avoiding a real parser, treating configuration as code, or executing user input from a web request. If the input came from outside your trust boundary, executing it directly is usually a design error.
Common Pitfalls
- Using
evalorexecon untrusted input and treating a restricted namespace as complete security. - Reaching for dynamic execution when
ast.literal_eval, JSON, or a real configuration format would solve the problem safely. - Expecting
execto return a value directly instead of reading results from a namespace dictionary. - Mixing executed code with module globals and making side effects difficult to track.
- Forgetting that
evalonly supports expressions whileexechandles statements and multi-line code.
Summary
- Use
evalfor simple expressions andexecfor statements or multi-line code. - Pass explicit namespace dictionaries so execution does not leak unpredictably into module state.
- Prefer safer parsing tools such as
ast.literal_evalwhen the input is data rather than code. - Compile reused dynamic code once when performance matters.
- Never treat raw execution of untrusted strings as a safe default.

