我有一个这样的变量形式描述的表达式
's1*3 - (s2-s1)*1'
我给出了s1和s2的值,可以根据需要进行更改
我可以使用python ast模块通过替换相应的s1和s2值(s1 = 20,s2 = 30)来评估此表达式
import ast
import operator as op
operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul,
ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor,
ast.USub: op.neg}
def eval_(node):
if isinstance(node, ast.Num): # <number>
return node.n
elif isinstance(node, ast.BinOp): # <left> <operator> <right>
return operators[type(node.op)](eval_(node.left), eval_(node.right))
elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
return operators[type(node.op)](eval_(node.operand))
else:
raise TypeError(node)
>>> str1 = '20*3 - (30-20)*1'
>>> node = ast.parse(str1, mode='eval')
>>> eval_(node.body)
50
我应该如何评估此表达式,而无需将变量替换为其实际值。
谢谢
您可以使用eval
function。但是您必须谨慎使用,eval
因为它会执行任何字符串,如果您接受从不可信输入中求值的字符串,可能会非常危险。例如,假设要评估的字符串是"os.system('rm -rf /')"
?它将真正开始删除计算机上的所有文件。
>>> eval('20*3 - (30-20)*1')
50
作为更好的解决方案,您可以使用python的内部编译器解析方程式:
>>> s1=20
>>> s2=30
>>> eq='s1*3 - (s2-s1)*1'
>>> compiler.parse( eq )
Module(None, Stmt([Discard(Sub((Mul((Name('s1'), Const(3))), Mul((Sub((Name('s2'), Name('s1'))), Const(1))))))]))
因此,如果您想评估方程式,input
那么使用compile
和评估这个比使用更安全的方法!
>>> eq='s1*3 - (s2-s1)*1'
>>> a=compile(eq,'','eval')
>>> eval(a)
50
您也可以将sympy
其用作符号数学的Python库。它旨在成为一个功能齐全的计算机代数系统(CAS),同时保持代码尽可能的简单,以便于理解和易于扩展。SymPy完全用Python编写,不需要任何外部库。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句