内置函数 eval() 可以将字符串形式的表达式当作 Python 代码进行执行,并返回表达式的结果。
虽然 eval() 在某些场景下可以简化代码、提升灵活性,但它也存在严重的安全风险。因此,掌握它的原理、使用场景与限制,对于写出安全、健壮的 Python 程序至关重要。
一、函数语法
eval(expression, globals=None, locals=None)
参数:
expression :字符串类型,必须是一个合法的 Python 表达式(不是完整语句,比如不能是 for 或 def)。
globals :可选。用于指定全局命名空间(字典形式)。
locals :可选。用于指定局部命名空间(字典形式)。
返回值:
执行表达式后的计算结果。
二、基本用法举例
1、计算字符串形式的数学表达式
expr = "3 * (4 + 5)"result = eval(expr)print(result) # 输出:27
2、直接使用变量
x = 10print(eval("x + 5")) # 输出:15
3、动态访问对象属性
class Person: name = "Alice"
print(eval("Person.name")) # 输出:Alice
4、控制执行环境(使用 globals 和 locals)
为了避免 eval() 执行危险代码,可以通过设置受限的作用域。
示例:限制变量访问
expr = "x + y"globals_dict = {"x": 5}locals_dict = {"y": 10}print(eval(expr, globals_dict, locals_dict)) # 输出:15
示例:禁用内置函数(安全沙箱)
safe_globals = {"__builtins__": None}eval("2 + 3", safe_globals) # 输出:5
提示:
这种“沙箱”机制并不完全可靠,不建议用于非信任来源的输入。
三、安全风险与替代方案
eval() 会执行任意代码,一旦处理了来自不可信来源的字符串,极易导致安全漏洞,例如:
user_input = "__import__('os').system('rm -rf /')" # ❌ 危险!eval(user_input)
可能会造成文件被删除、数据泄露以及权限被控制等情况。
替代方案:
(1)若只是用于表达式计算,可使用 ast.literal_eval()(更安全)。
ast.literal_eval() 只能安全解析 Python 字面量(如字符串、数字、列表、字典、元组等)
import ast
print(ast.literal_eval("{'a': 1, 'b': 2}")) # ✅ 安全# print(ast.literal_eval("os.system('ls')")) # ❌ 报错,阻止危险操作
(2)若处理复杂语句,应使用 exec(),但风险可能更大。
(3)若仅为数学表达式计算,可使用 operator 模块、第三方库如 numexpr、sympy。
四、补充说明
1、不要在生产代码中直接使用 eval() 处理用户数据。
2、尽可能使用专用解析函数替代。
3、如果必须使用,务必限制执行环境(如禁用内建函数)并严格校验输入格式。
4、总之,能不用 eval() 的地方,最好不要用。非用不可的地方,也要加倍小心。
“点赞有美意,赞赏是鼓励”