Python Python compile(): Compile Source to Code Objects — Syntax, Modes (exec…
page info

본문

Python compile(): Turn source code into executable code objects
The built-in compile()
function converts Python source into a code object that can be executed or evaluated with exec()
or eval()
. It supports multiple modes (exec
, eval
, single
), optional flags, and integrates with the AST for advanced tooling.
Syntax
compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
- source: A string of Python code or an AST object.
- filename: A string used in tracebacks (e.g.,
"<stdin>"
, file path). - mode:
"exec"
for statements,"eval"
for a single expression,"single"
for a single interactive statement. - flags/dont_inherit: Control future features or inherit compiler flags from the environment.
- optimize: Optimization level; typically
-1
(interpreter default), or0
,1
,2
.
Quick examples
# 1) Evaluate an expression
code = compile("3 * (2 + 5)", "<expr>", "eval")
print(eval(code)) # 21
# 2) Execute statements with a namespace
src = "x = 10\ny = x ** 2"
ns = {}
exec(compile(src, "script.py", "exec"), ns)
print(ns["y"]) # 100
# 3) Interactive mode ('single') prints the result of a single statement
single_code = compile("print(1 + 2)", "<repl>", "single")
exec(single_code) # 3
Modes explained
- "exec": Multiple statements, function/class definitions, imports; use with
exec()
. - "eval": A single expression; use with
eval()
to get a return value. - "single": A single interactive statement; echoes the result like a REPL.
# 'eval' requires an expression only
expr_code = compile("sum([1,2,3])", "<sum>", "eval")
print(eval(expr_code)) # 6
Using globals/locals and sandboxes
Control the execution environment with explicit globals
/locals
. Use restricted dictionaries to limit access.
safe_globals = {"__builtins__": {"abs": abs}}
safe_locals = {}
code = compile("abs(-7)", "<sandbox>", "eval")
print(eval(code, safe_globals, safe_locals)) # 7
Filename and errors
filename
appears in tracebacks, aiding debugging. SyntaxError
and ValueError
are common compile-time issues.
try:
compile("for", "bad.py", "exec")
except SyntaxError as e:
print(e) # invalid syntax (bad.py, line 1)
Flags, future features, and optimize
Compiler flags
enable future features or alter parsing. optimize
tweaks bytecode optimization; higher settings may remove asserts or inline constants.
src = "a = 1/2" # With 'from __future__ import division' in flags, changes division behavior in older versions
code = compile(src, "<future>", "exec", flags=0, optimize=1)
exec(code)
AST integration
Compile an AST for static analysis or transformations. Use the ast
module to parse, modify, and compile.
import ast
tree = ast.parse("x = 2 * 3", filename="prog.py", mode="exec")
code = compile(tree, "prog.py", "exec")
ns = {}
exec(code, ns)
print(ns["x"]) # 6
Security considerations
- Never compile/eval untrusted input: It can execute arbitrary code.
- Restrict builtins and namespaces: If you must evaluate dynamic code, strictly limit the environment.
- Validate and whitelist: Consider custom parsers or domain-specific languages instead of raw Python.
Performance and caching
- Reuse code objects: Pre-compile hot paths and
exec
/eval
repeatedly. - Avoid string parsing in loops: Compile outside the loop; execute inside.
- Bytecode caching: The import system caches module bytecode (
.pyc
), but manualcompile()
does not auto-cache.
# Pre-compile for repeated use
code = compile("x + y", "<fast>", "eval")
def fast_eval(x, y):
return eval(code, {"x": x, "y": y})
print(fast_eval(3, 4)) # 7
Common pitfalls
- Wrong mode: Using
"eval"
for statements raisesSyntaxError
. - Missing globals:
NameError
if referenced names aren’t provided in the namespace. - Invisible side effects:
exec()
modifies the provided dicts—inspect them after execution.
FAQ
- What does
compile()
return? - A code object suitable for
exec()
oreval()
. - Can I compile partial code?
- Yes, but it must be syntactically valid for the chosen mode.
- How do I capture printed output?
- Redirect
sys.stdout
or run in a subprocess;compile()
itself doesn’t handle IO. - Is compiling faster than importing?
- Import uses its own machinery and caches bytecode.
compile()
is for dynamic code—not a replacement for imports.
Related keywords
Python compile, code object, exec, eval, AST, flags, optimize, REPL single mode, sandboxing, dynamic execution
comment list
There are no registered comments.