前言
大家好,我是倔强青铜三。欢迎关注我,微信公众号:倔强青铜三。欢迎点赞、收藏、关注,一键三连!!!
欢迎来到 Python 百日冲刺第 37 天!
今天聊一把双刃剑——eval()
。它能瞬间把字符串变成可执行代码,也能瞬间把服务器变成“矿机”。看完这篇,你会明白何时该用、何时该躲,以及如何用更安全的姿势“白嫖”动态求值。
🧠 eval()
是什么?
eval(expression)
把字符串当作 Python 表达式执行并返回结果:
result = eval("3 + 5")print(result) # 8
看似魔法,实则风险拉满。
🚨 危险现场
一旦让外部用户控制输入,eval()
就可能执行任意代码:
user_input = "__import__('os').system('rm -rf /')"eval(user_input) # 毁灭吧,系统!
哪怕一句 open('secret.txt').read()
也能泄露隐私。
✅ 何时才能用?
- 输入完全可信(如内部脚本、自动生成表达式)。需求必须动态求值。
即使满足,也优先考虑更安全的替代方案。
🔐 安全替代方案
1️⃣ ast.literal_eval()
—— 最推荐
只解析字面量:字符串、数字、列表、字典、布尔值、None。
import astexpr = "{'name': 'Alice', 'age': 30}"safe_result = ast.literal_eval(expr)print(safe_result) # {'name': 'Alice', 'age': 30}
无法调用函数、无法导入模块,安全感直接拉满。
2️⃣ 用 JSON 做数据交换
结构化数据优先 JSON:
import jsondata = json.loads('{"a": 10, "b": 20}')
跨语言、跨平台、零风险。
⚙️ 受限 eval()
:最后的倔强
若必须 eval()
,可通过 globals
与 locals
限制作用域:
safe_globals = {"__builtins__": None}safe_locals = {"x": 10, "y": 5}expr = "x + y"result = eval(expr, safe_globals, safe_locals)print(result) # 15
缺点:绕过姿势千千万,依旧不推荐直接用于用户输入。
🛠️ 正当用例(仅限内部)
- 自研计算器 Demo(无网络、无用户输入)。数据科学 Notebook 中完全可信的表达式。受控沙箱里的内部工具。
🔄 速查表
场景 | 建议使用 | 千万别用 |
---|---|---|
动态字面量 | ast.literal_eval | eval |
用户输入 | JSON/ast | 裸 eval |
复杂逻辑 | 写函数 | eval 拼接字符串 |
✅ TL;DR 一句话总结
eval()
能跑,但别让它乱跑。对外输入 → 永远不用 eval()
。真要字面量 → ast.literal_eval()
真香。最后感谢阅读!欢迎关注我,微信公众号:
倔强青铜三
。欢迎点赞
、收藏
、关注
,一键三连!!!