
本文介绍如何在 python 函数中安全、正确地使用 eval() 执行以函数参数为变量的动态表达式,重点解决因作用域导致的 nameerror 问题,并避免覆盖内置模块名等常见陷阱。
本文介绍如何在 python 函数中安全、正确地使用 eval() 执行以函数参数为变量的动态表达式,重点解决因作用域导致的 nameerror 问题,并避免覆盖内置模块名等常见陷阱。
在 Python 中,eval() 默认在当前局部/全局命名空间中执行字符串表达式,但当表达式引用的是函数形参(如 x)时,由于 eval() 不自动继承函数的局部作用域,会抛出 NameError: name 'x' is not defined 错误。根本原因在于:eval() 的默认作用域不包含函数的局部变量。
要解决该问题,需显式传入变量映射字典作为 eval() 的第二个参数(globals),将函数参数绑定为可访问的名称:
def system(into):
x = into # 假设 into 是一个列表,如 [2, 3]
# ✅ 正确:将 x 显式注入 eval 的命名空间
sis = [eval(expr, {'x': x}) for expr in equations]
return sis
if __name__ == "__main__":
equations = ['x[0] + x[1]', '2 * x[0] - 3 * x[1]']
result = system([2, 3]) # → [5, -5]
print(result)
⚠️ 关键注意事项:
- 禁止使用 sys 作为变量名:sys 是 Python 标准库内置模块(import sys),将其用作自定义变量名可能导致意外覆盖或导入冲突。应改用语义清晰的名称,如 equations 或 expr_list。
-
避免滥用 global:原代码中 global sys 不仅冗余(未在函数内赋值),还掩盖了设计缺陷;推荐将表达式列表作为参数传入,提升可测试性与可维护性:
def system(into, expressions): x = into return [eval(expr, {'x': x}) for expr in expressions] - 安全警告:eval() 存在严重安全风险,绝不应用于不可信输入(如用户提交的字符串)。生产环境建议优先使用 ast.literal_eval()(仅支持字面量)或专用数学表达式解析库(如 simpleeval、numexpr)替代。
总结:通过显式构造 eval() 的 globals 字典传递所需变量,可精准控制求值上下文;同时遵循命名规范、避免全局状态、审慎评估安全性,才能写出健壮、可维护的动态计算逻辑。











