Оценка математического выражения
Каков наилучший способ реализовать программу на 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/
Это позволяет вам оценить ограниченное заявление, которое не может нанести вред вашему компьютеру или вашей программе.