我如何(轻松)获取一个字符串,例如"sin(x)*x^2"
用户在运行时可能输入的字符串,并生成一个 Python 函数,该函数可以针对 的任何值进行评估x
?
7 回答
如果您使用 Python 表示法,Python 自己的内部编译器可以解析它。
如果你稍微改变一下符号,你会更开心。
import compiler
eq= "sin(x)*x**2"
ast= compiler.parse( eq )
您将获得一个可以使用的抽象语法树。
您可以使用 Python parser
:
import parser
from math import sin
formula = "sin(x)*x**2"
code = parser.expr(formula).compile()
x = 10
print(eval(code))
它比纯的性能更好eval
,当然,避免了代码注入!
f = parser.parse('sin(x)*x^2').to_pyfunc()
parser
可以使用 PLY、pyparsing、内置标记器、解析器、ast 定义哪里。
不要eval
在用户输入上使用。
pyparsing 可能会做你想做的事(http://pyparsing.wikispaces.com/),特别是如果字符串来自不受信任的来源。
另请参阅http://pyparsing.wikispaces.com/file/view/fourFn.py以获得使用它构建的功能相当全的计算器。
为了强调 JF Sebastian 的建议,“eval”甚至“编译器”解决方案都可能存在细微的安全漏洞。输入的可信度如何?使用“编译器”,您至少可以从 AST 中过滤掉诸如 getattr 查找之类的东西,但我发现使用 PLY 或 pyparsing 处理这类事情比确保让 Python 提供帮助的结果更容易。
此外,“编译器”笨拙且难以使用。它已在 3.0 中弃用并删除。您应该使用“ast”模块(在 2.6 中添加,在 2.5 中作为“_ast”提供)。
与vartec达成一致。我会使用 SymPy - 特别是 lambdify 函数应该完全符合您的要求。
见:http ://showmedo.com/videotutorials/video?name=7200080&fromSeriesID=720
对此有一个很好的解释。
最良好的祝愿,