一句话总结
| 函数 |
能做什么 |
返回值 |
eval() |
求值单个表达式 |
表达式的计算结果 |
exec() |
执行任意语句块 |
None |
compile() |
将源码编译为字节码对象 |
字节码对象(code object) |
1. eval() — 表达式求值
只能接受表达式,不能接受语句(如 if、for、赋值 等)。
1 2 3 4 5 6 7 8
| >>> eval("1 + 2") 3
>>> eval("len('hello')") 5
>>> eval("x = 1") SyntaxError: invalid syntax
|
2. exec() — 执行代码块
可以执行任何 Python 语句:函数定义、类定义、循环、条件、赋值等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| >>> exec("print('hello')") hello
>>> code = """ ... def foo(): ... return 42 ... ... foo() ... """ >>> exec(code) 42
>>> exec("x = 1 + 2") >>> x 3
|
返回值始终是 None。
3. compile() — 编译源码
把字符串源码编译成字节码对象(code object),可以延迟执行或反复执行。
1 2 3 4 5 6 7 8 9 10 11 12 13
| >>> >>> c = compile("1 + 2", "<string>", "eval") >>> eval(c) 3
>>> >>> c = compile("x = 1", "<string>", "exec") >>> exec(c)
>>> >>> c = compile("print('hi')", "<string>", "single") >>> exec(c) hi
|
三种模式:
| 模式 |
适用场景 |
配合 |
"eval" |
单个表达式 |
eval() |
"exec" |
语句块 |
exec() |
"single" |
交互式单条语句 |
exec() |
三者关系图
源码字符串 ──compile()──▶ 字节码对象 ──eval()/exec()──▶ 执行结果
compile() 是编译阶段,把字符串变成可执行的字节码
eval() / exec() 是执行阶段,运行字节码或源码
1 2 3 4 5 6
| eval("1 + 2") eval(compile("1 + 2", "<s>", "eval"))
exec("x = 1") exec(compile("x = 1", "<s>", "exec"))
|
实际应用场景
1 2 3 4 5 6 7 8 9 10 11 12 13
| user_code = input("请输入Python代码: ") exec(user_code)
code_obj = compile(open("script.py").read(), "script.py", "exec") for _ in range(1000): exec(code_obj)
safe_expr = eval(compile("2 ** 10", "<sandbox>", "eval"), {"__builtins__": {}}, {})
|
⚠️ 安全警告
三者都能执行任意代码,不要对不可信的输入使用它们:
1 2
| eval("__import__('os').system('rm -rf /')")
|
如需安全求值,考虑用 ast.literal_eval() 替代 eval(),它只支持字面量解析。