10

实现一个接受字符串并根据运算符优先级输出其结果的python程序的最佳方法是什么(例如:“4 + 3 * 5”将输出19)。我已经用谷歌搜索了解决这个问题的方法,但它们都太复杂了,我正在寻找一个(相对)简单的方法。

澄清:我需要比 eval() 稍微高级一点的东西 - 我希望能够添加其他运算符(例如最大运算符 - 4$2 = 4),或者,我在学术上对这个比对专业更感兴趣 - 我想知道如何做到这一点。

4

6 回答 6

16

如果您“对学术感兴趣”,您想了解如何编写具有运算符优先级的解析器。

Python 中的 Simple Top-Down Parsing是一篇不错的文章,它构建了一个示例解析器来完全执行您想做的事情:评估数学表达式。

我强烈建议您尝试编写自己的第一个解析器——这是“啊,这就是它的工作原理”的时刻之一!

于 2009-10-09T18:59:59.297 回答
2

这就是“eval”函数在 Python 中所做的事情。

result = eval(expression)

请注意,尽管它可以做更多事情,主要是调用函数,所以为了安全起见,您应该确保它不能访问本地变量或全局变量。此外,您可以访问内置方法,包括棘手的导入,因此您还需要阻止对它的访问:

result = eval(expression, {'__builtins__': None}, {})

但这只是在您需要安全性的情况下,也就是说,如果您允许任何人输入任何表达式。

当然,由于您以这种方式阻止了所有 locla 变量的使用,因此您没有任何变量要使用,因此您只需要传入那些应该在字典中访问的变量。

vars = {'__builtins__': None, 'x': x}
result = eval(expression, vars, {})

或类似的。

于 2009-10-09T18:45:36.037 回答
2

另一种可能性是查看Pyparsing,它是一个通用的解析器构建器。它比您需要的更强大,但实施起来可能更快。

于 2009-10-09T20:08:43.637 回答
1

我对 Python 和任何极其 Pythonic 的方法都不是很熟悉,但你可以看看在《四人帮》一书中定义的解释器模式。它是为处理“语言”而设计的,数学表达式确实遵循具有规则的特定语言。实际上,Wikipedia 上的示例实际上是 RPN 计算器的 Java 实现。

于 2009-10-09T18:39:03.383 回答
0

java替代品在这里http://code.google.com/p/expressionoasis/

于 2010-10-29T18:45:30.057 回答
0

此收据为您的问题提供了正确的答案:

http://code.activestate.com/recipes/496746-restricted-safe-eval/

它允许您评估不会损害您的计算机或程序的有限语句。

于 2011-02-25T09:48:23.283 回答