Python 中的方程式解析
- 2025-02-11 09:51:00
- admin 原创
- 54
问题描述:
"sin(x)*x^2"
我怎样才能(轻松地)获取用户在运行时输入的字符串并生成可以对任何值进行评估的 Python 函数x
?
解决方案 1:
如果您使用 Python 符号,Python 自己的内部编译器可以解析它。
如果你稍微改变一下符号,你会更高兴。
import compiler
eq= "sin(x)*x**2"
ast= compiler.parse( eq )
您将获得一个可以使用的抽象语法树。
解决方案 2:
EDIT parser
在 Python 3.9 中已弃用:https://docs.python.org/3/whatsnew/3.9.html#new-parser
您可以使用Python parser
:
import parser
from math import sin
formula = "sin(x)*x**2"
code = parser.expr(formula).compile()
x = 10
print(eval(code))
它的性能比纯粹的更好eval
,当然,避免了代码注入!
解决方案 3:
f = parser.parse('sin(x)*x^2').to_pyfunc()
可以parser
使用 PLY、pyparsing、内置 tokenizer、parser、ast 进行定义。
不要eval
在用户输入时使用。
解决方案 4:
pyparsing 可能会做你想做的事(http://pyparsing.wikispaces.com/),特别是当字符串来自不受信任的来源时。
另请参阅http://pyparsing.wikispaces.com/file/view/fourFn.py,了解使用它构建的功能相当齐全的计算器。
解决方案 5:
为了强调 JF Sebastian 的建议,“eval”甚至“编译器”解决方案都可能存在微妙的安全漏洞。输入有多可信?使用“编译器”,您至少可以从 AST 中过滤掉诸如 getattr 查找之类的内容,但我发现使用 PLY 或 pyparsing 进行此类操作比让 Python 提供帮助来确保结果安全更容易。
此外,“编译器”很笨拙,难以使用。它在 3.0 中已被弃用并被删除。您应该使用“ast”模块(在 2.6 中添加,在 2.5 中可用作“_ast”)。
解决方案 6:
Sage旨在替代 matlab,在介绍视频中,它演示了如何处理与您的情况类似的情况。它们似乎支持多种方法。由于代码是开源的,您可以浏览并亲自了解作者如何处理此类情况。