Оценка математического выражения

Каков наилучший способ реализовать программу на Python, которая будет принимать строку и выводить свой результат в соответствии с приоритетом оператора (например: "4+3*5" будет выводить 19). Я гуглил способы решения этой проблемы, но все они были слишком сложными, и я ищу (относительно) простой.

уточнение: мне нужно что-то более продвинутое, чем eval() - я хочу иметь возможность добавлять другие операторы (например, оператор максимума - 4$2 = 4) или, кроме того, меня это больше интересует академически, чем профессионально - я хочу знаю, как это сделать.

6 ответов

Решение

Если вы "академически заинтересованы", вы хотите узнать, как написать синтаксический анализатор с приоритетом оператора.

Простой синтаксический анализ сверху вниз в Python - это хорошая статья, в которой создается пример синтаксического анализатора, который делает именно то, что вы хотите: оценивать математические выражения.

Я очень рекомендую попробовать написать свой первый парсер - это один из тех моментов "ах, вот как это работает"!

Вот что делает функция "eval" в Python.

result = eval(expression)

Остерегайтесь, хотя он может делать намного больше, в первую очередь вызывать функции, поэтому, чтобы быть в безопасности, вы должны убедиться, что он не может получить доступ к локальным или глобальным объектам. Кроме того, вы можете получить доступ к встроенным методам, включая сложный импорт, поэтому вам также необходимо заблокировать доступ к нему:

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

Но это только в том случае, если вам нужна безопасность, то есть если вы позволяете кому-либо вводить любое выражение.

Конечно, поскольку вы таким образом блокируете все переменные locla от использования, у вас нет никаких переменных для использования, поэтому для этого вам нужно передать только те переменные, к которым следует обращаться в словарях.

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

или похожие.

Другая возможность - взглянуть на Pyparsing, который является основным компоновщиком парсера. Он более мощный, чем вам нужно, но он может быть быстрее реализован.

Я не очень знаком с Python и любыми чрезвычайно Pythonic методами, но вы можете взглянуть на шаблон Interpreter, который определен в книге "Банды четырех". Он предназначен для обработки "языка", а математические выражения следуют определенному языку с правилами. Фактически, пример в Википедии - это Java-реализация калькулятора RPN.

Альтернатива Java здесь http://code.google.com/p/expressionoasis/

Этот рецепт дает правильный ответ на вашу проблему:

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

Это позволяет вам оценить ограниченное заявление, которое не может нанести вред вашему компьютеру или вашей программе.

Другие вопросы по тегам