You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否存在可安全对简单表达式求值的Python模块?

可选方案1:使用第三方库 simpleeval(最便捷)

这是专门为安全表达式求值设计的轻量库,默认屏蔽了所有危险执行逻辑,原生支持比较运算、算术运算、逻辑运算等常用简单表达式需求,不需要自己处理语法解析逻辑。

  • 安装方式:pip install simpleeval
  • 使用示例:
from simpleeval import simple_eval

# 基础比较运算
print(simple_eval("1 > 0"))  # 输出 True
# 支持传入自定义变量
print(simple_eval("a + b >= 10", names={"a": 3, "b": 8}))  # 输出 True
# 支持逻辑运算
print(simple_eval("1 < 2 and 3 > 2"))  # 输出 True

它默认禁用了函数调用、属性访问、导入等危险操作,不会出现eval的代码注入风险,足够覆盖绝大多数简单表达式求值场景。

可选方案2:基于ast自定义解析(无第三方依赖)

如果不想引入额外依赖,可以自己基于ast模块做白名单控制,只允许你需要的语法节点类型,示例实现如下:

import ast
import operator

# 配置允许的运算符白名单,可按需扩展
ALLOWED_OPS = {
    # 算术运算符
    ast.Add: operator.add,
    ast.Sub: operator.sub,
    ast.Mult: operator.mul,
    ast.Div: operator.truediv,
    # 比较运算符
    ast.Gt: operator.gt,
    ast.Lt: operator.lt,
    ast.Eq: operator.eq,
    ast.GtE: operator.ge,
    ast.LtE: operator.le,
    ast.NotEq: operator.ne,
    # 逻辑运算符
    ast.And: lambda a,b: a and b,
    ast.Or: lambda a,b: a or b,
}

def safe_eval(expr: str):
    ast_root = ast.parse(expr, mode='eval').body
    def parse_node(node):
        if isinstance(node, ast.Constant):
            return node.value
        elif isinstance(node, ast.BinOp):
            op_cls = type(node.op)
            if op_cls not in ALLOWED_OPS:
                raise ValueError(f"不支持的运算符:{op_cls.__name__}")
            return ALLOWED_OPS[op_cls](parse_node(node.left), parse_node(node.right))
        elif isinstance(node, ast.Compare):
            left_val = parse_node(node.left)
            for op, comp_node in zip(node.ops, node.comparators):
                op_cls = type(op)
                if op_cls not in ALLOWED_OPS:
                    raise ValueError(f"不支持的运算符:{op_cls.__name__}")
                comp_val = parse_node(comp_node)
                if not ALLOWED_OPS[op_cls](left_val, comp_val):
                    return False
                left_val = comp_val
            return True
        elif isinstance(node, ast.BoolOp):
            op_cls = type(node.op)
            if op_cls not in ALLOWED_OPS:
                raise ValueError(f"不支持的逻辑运算符:{op_cls.__name__}")
            res = parse_node(node.values[0])
            for val_node in node.values[1:]:
                res = ALLOWED_OPS[op_cls](res, parse_node(val_node))
            return res
        else:
            raise ValueError(f"不支持的语法节点:{type(node).__name__}")
    return parse_node(ast_root)

# 测试
print(safe_eval("1 > 0"))  # 输出 True
print(safe_eval("2 + 3 * 5 > 10")) # 输出 True

这种方案完全可控,你可以根据自己的需求扩展允许的语法类型,不会有额外的安全风险。

内容的提问来源于stack exchange,提问作者sasano8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 03:36:04