Оценка математического выражения - PullRequest
10 голосов
/ 09 октября 2009

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

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

Ответы [ 6 ]

16 голосов
/ 09 октября 2009

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

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

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

2 голосов
/ 10 октября 2009

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

2 голосов
/ 09 октября 2009

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

result = eval(expression)

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

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

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

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

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

или аналогичный.

1 голос
/ 09 октября 2009

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

0 голосов
/ 25 февраля 2011

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

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

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

0 голосов
/ 29 октября 2010

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

...