实现一个接受字符串并根据运算符优先级输出其结果的python程序的最佳方法是什么(例如:“4 + 3 * 5”将输出19)。我已经用谷歌搜索了解决这个问题的方法,但它们都太复杂了,我正在寻找一个(相对)简单的方法。
澄清:我需要比 eval() 稍微高级一点的东西 - 我希望能够添加其他运算符(例如最大运算符 - 4$2 = 4),或者,我在学术上对这个比对专业更感兴趣 - 我想知道如何做到这一点。
实现一个接受字符串并根据运算符优先级输出其结果的python程序的最佳方法是什么(例如:“4 + 3 * 5”将输出19)。我已经用谷歌搜索了解决这个问题的方法,但它们都太复杂了,我正在寻找一个(相对)简单的方法。
澄清:我需要比 eval() 稍微高级一点的东西 - 我希望能够添加其他运算符(例如最大运算符 - 4$2 = 4),或者,我在学术上对这个比对专业更感兴趣 - 我想知道如何做到这一点。
如果您“对学术感兴趣”,您想了解如何编写具有运算符优先级的解析器。
Python 中的 Simple Top-Down Parsing是一篇不错的文章,它构建了一个示例解析器来完全执行您想做的事情:评估数学表达式。
我强烈建议您尝试编写自己的第一个解析器——这是“啊,这就是它的工作原理”的时刻之一!
这就是“eval”函数在 Python 中所做的事情。
result = eval(expression)
请注意,尽管它可以做更多事情,主要是调用函数,所以为了安全起见,您应该确保它不能访问本地变量或全局变量。此外,您可以访问内置方法,包括棘手的导入,因此您还需要阻止对它的访问:
result = eval(expression, {'__builtins__': None}, {})
但这只是在您需要安全性的情况下,也就是说,如果您允许任何人输入任何表达式。
当然,由于您以这种方式阻止了所有 locla 变量的使用,因此您没有任何变量要使用,因此您只需要传入那些应该在字典中访问的变量。
vars = {'__builtins__': None, 'x': x}
result = eval(expression, vars, {})
或类似的。
另一种可能性是查看Pyparsing,它是一个通用的解析器构建器。它比您需要的更强大,但实施起来可能更快。
我对 Python 和任何极其 Pythonic 的方法都不是很熟悉,但你可以看看在《四人帮》一书中定义的解释器模式。它是为处理“语言”而设计的,数学表达式确实遵循具有规则的特定语言。实际上,Wikipedia 上的示例实际上是 RPN 计算器的 Java 实现。
此收据为您的问题提供了正确的答案:
http://code.activestate.com/recipes/496746-restricted-safe-eval/
它允许您评估不会损害您的计算机或程序的有限语句。