安全地评估简单的字符串方程式

发布于 2021-01-29 18:27:14

我正在编写一个程序,其中将方程式作为字符串输入,然后求值。到目前为止,我已经提出了:

test_24_string = str(input("Enter your answer: "))
test_24 = eval(test_24_string)

我既需要此方程式的字符串版本,也需要评估的版本。但是,这eval是非常危险的功能。int()但是,使用是行不通的,因为这是一个方程式。是否存在一个Python函数,该函数将评估字符串中的数学表达式,就像输入数字一样?

关注者
0
被浏览
45
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    一种方法是使用numexpr。它主要是用于优化(和多线程)numpy操作的模块,但它也可以处理数学python表达式:

    >>> import numexpr
    >>> numexpr.evaluate('2 + 4.1 * 3')
    array(14.299999999999999)
    

    您可以调用.item结果以获取类似python的类型:

    >>> numexpr.evaluate('17 / 3').item()
    5.666666666666667
    

    它是一个第三方扩展模块,因此在这里可能会完全被淘汰,但是它绝对比其他应用程序更安全,eval并且支持许多功能(包括numpymath操作)。如果还支持“变量替换”:

    >>> b = 10
    >>> numexpr.evaluate('exp(17) / b').item()
    2415495.27535753
    

    python标准库的一种方法,尽管非常有限ast.literal_eval。它适用于Python中最基本的数据类型和文字:

    >>> import ast
    >>> ast.literal_eval('1+2')
    3
    

    但是以更复杂的表达式失败,例如:

    >>> ast.literal_eval('import os')
    SyntaxError: invalid syntax
    
    >>> ast.literal_eval('exec(1+2)')
    ValueError: malformed node or string: <_ast.Call object at 0x0000023BDEADB400>
    

    不幸的是,除了+-不可能的任何运算符:

    >>> ast.literal_eval('1.2 * 2.3')
    ValueError: malformed node or string: <_ast.BinOp object at 0x0000023BDEF24B70>
    

    我在此处复制了部分文档,其中包含受支持的类型:

    安全地评估表达式节点或包含Python文字或容器显示的字符串。提供的字符串或节点只能由以下Python文字结构组成:字符串,字节,数字,元组,列表,字典,集合,布尔值和无。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看