Python 动态执行字符串代码:eval 与 exec 用法及安全实践

叶初
叶初
发布时间:2026-10-12| 2人浏览过
原创

在 Python 中利用字符串动态执行代码时,eval 与 exec 是最常用的内置工具。eval 专门用于计算表达式并返回结果,而 exec 用于执行多条语句且不返回值。本文详解两者的核心差异、现代 Python 的正确调用姿势,并提供安全的代码替代方案与常见报错排查指南。

eval 与 exec 的核心定位与区别

在实际开发中,经常需要将存储在字符串或配置文件中的逻辑直接运行。Python 提供了两种底层机制来实现这一需求,它们的分工非常明确:

  • eval():仅接收单个表达式字符串,解析后计算其值并返回结果。它不能执行赋值或流程控制语句,否则将抛出异常。
  • exec():接收包含完整语句(如赋值、循环、函数定义、多次 print 等)的代码块,按顺序执行但不返回任何值(隐式返回 None)。

需要注意的是,早期 Python 2 版本中 exec 仅为保留关键字(语句),而在现代 Python 3 环境中,它已与 eval 一样成为标准的内置函数,参数签名也更为完善。

第1步:使用 eval 计算表达式并返回值

当你的目标是获取某个数学运算、数据访问或对象属性调用的最终结果时,应使用 eval。它的入口为内置命名空间,动作是传入被双引号或单引号包裹的合法表达式。

# 基础数值与运算符计算
result = eval("2 + 3 * 4")
print(result)  # 输出:14

# 支持字典键值访问与列表切片
d = {"score": 85}
grade = eval('d["score"] + 5')
print(grade)   # 输出:90

完成判断标准:控制台准确输出表达式的计算结果,未触发 SyntaxError 或 NameError。

第2步:使用 exec 执行多行语句或配置脚本

若需运行包含变量初始化、条件分支或多次输出的代码片段,请改用 exec。它允许你一次性注入并运行多行文本。

code_str = """
x = 10
y = 20
if x > y:
    print("X大于Y")
else:
    print("Y大于等于X")
total = x + y
"""

exec(code_str)
print("累计总和:", total)  # 输出:累计总和: 30

完成判断标准:字符串内的全部语句按顺序执行完毕,定义的变量成功写入当前作用域,且没有返回阻塞信息。

第3步:处理外部文件中的动态代码(替代已移除的 execfile)

在 Python 2 时代存在内建函数 execfile() 用于直接运行 .py 文件。该函数已在 Python 3 中被彻底移除。现代环境推荐使用 open() 读取内容后交由 exec 执行,或配合 compile() 提升安全性与灵活性。

# 安全读取并执行本地脚本文件
file_path = "config_script.py"
try:
    with open(file_path, "r", encoding="utf-8") as f:
        file_code = f.read()
    # 编译为字节码对象后再执行,可捕获语法错误
    compiled = compile(file_code, file_path, "exec")
    exec(compiled)
except FileNotFoundError:
    print("目标文件未找到,请检查路径")
except SyntaxError as e:
    print(f"脚本语法有误,位置:{e.lineno}")

完成判断标准:脚本正常加载执行,内部定义的逻辑生效;若文件缺失或包含非法语法,程序能平稳打印错误日志而不崩溃。

核心注意事项与安全风险排错

动态代码执行是一把双刃剑。直接使用 eval(user_input) 处理不可信的用户输入会导致严重的远程代码执行漏洞。攻击者可构造类似 "__import__('os').system('rm -rf /')" 的字符串接管进程权限。

安全排错与替代建议:

  1. 拦截恶意函数调用:在执行前清理上下文命名空间,或传递自定义的 globals 与 locals 字典限制可访问的内置模块。
  2. 使用字面量安全解析器:若仅需解析 JSON、字典、数字等数据结构,绝对不要使用 eval。请切换至 ast.literal_eval() 或标准库 json.loads(),它们只评估安全的数据字面量。
  3. 隔离执行环境:对于完全开放的动态逻辑,应在容器、沙箱或独立的轻量级进程中运行,避免污染主程序的内存与文件系统。

简要总结

掌握 eval() 与 exec() 的边界能有效提升 Python 脚本的灵活性。前者专注表达式求值与结果返回,后者负责多语句流水线执行。面对遗留的 execfile 写法应及时迁移至 compile() + exec() 组合。始终牢记:动态执行必须伴随严格的输入校验与作用域隔离,生产环境优先采用结构化数据解析替代原生字符串求值。以上就是 Python 动态执行字符串代码 eval 与 exec 用法的详细内容,更多关于 Python 高级进阶与安全编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。