41

我如何(轻松)获取一个字符串,例如"sin(x)*x^2"用户在运行时可能输入的字符串,并生成一个 Python 函数,该函数可以针对 的任何值进行评估x

4

7 回答 7

49

如果您使用 Python 表示法,Python 自己的内部编译器可以解析它。

如果你稍微改变一下符号,你会更开心。

import compiler
eq= "sin(x)*x**2"
ast= compiler.parse( eq )

您将获得一个可以使用的抽象语法树。

于 2009-02-27T11:12:34.280 回答
35

您可以使用 Python parser

import parser
from math import sin

formula = "sin(x)*x**2"
code = parser.expr(formula).compile()
x = 10
print(eval(code))

它比纯的性能更好eval,当然,避免了代码注入!

于 2011-05-09T12:23:11.413 回答
15
 f = parser.parse('sin(x)*x^2').to_pyfunc()

parser可以使用 PLY、pyparsing、内置标记器、解析器、ast 定义哪里。

不要eval在用户输入上使用。

于 2009-02-27T10:51:37.967 回答
8

pyparsing 可能会做你想做的事(http://pyparsing.wikispaces.com/),特别是如果字符串来自不受信任的来源。

另请参阅http://pyparsing.wikispaces.com/file/view/fourFn.py以获得使用它构建的功能相当全的计算器。

于 2010-03-29T12:11:39.333 回答
3

为了强调 JF Sebastian 的建议,“eval”甚至“编译器”解决方案都可能存在细微的安全漏洞。输入的可信度如何?使用“编译器”,您至少可以从 AST 中过滤掉诸如 getattr 查找之类的东西,但我发现使用 PLY 或 pyparsing 处理这类事情比确保让 Python 提供帮助的结果更容易。

此外,“编译器”笨拙且难以使用。它已在 3.0 中弃用并删除。您应该使用“ast”模块(在 2.6 中添加,在 2.5 中作为“_ast”提供)。

于 2009-02-27T11:57:10.227 回答
0

Sage旨在作为 matlab 替代品,在介绍视频中,它展示了如何处理与您的案例相似的情况。他们似乎支持广泛的方法。由于代码是开源的,您可以浏览并亲自查看作者如何处理此类情况。

于 2009-02-27T10:50:39.670 回答
0

与vartec达成一致。我会使用 SymPy - 特别是 lambdify 函数应该完全符合您的要求。

见:http ://showmedo.com/videotutorials/video?name=7200080&fromSeriesID=720

对此有一个很好的解释。

最良好的祝愿,

于 2010-03-29T11:44:17.513 回答