Как я могу (легко) взять строку, такую как "sin(x)*x^2"
, которая может быть введена пользователем во время выполнения и создать функцию Python, которая может быть оценена для любого значения x
?
Анализ выражений в Python
Ответ 1
Собственный внутренний компилятор Python может проанализировать это, если вы используете нотацию Python.
Если вы немного измените обозначение, вы будете счастливее.
import compiler
eq= "sin(x)*x**2"
ast= compiler.parse( eq )
Вы получаете абстрактное синтаксическое дерево, с которым вы можете работать.
Ответ 2
Вы можете использовать Python parser
:
import parser
formula = "sin(x)*x**2"
code = parser.expr(formula).compile()
from math import sin
x = 10
print eval(code)
Он работает лучше, чем чистый eval
и, конечно же, избегает инъекции кода!
Ответ 3
f = parser.parse('sin(x)*x^2').to_pyfunc()
Где parser
можно определить с помощью PLY, пирафинга, встроенного токенизатора, парсера, ast.
Не используйте eval
для ввода пользователем.
Ответ 4
pyparsing может делать то, что вы хотите (http://pyparsing.wikispaces.com/), особенно если строки из ненадежного источника.
См. также http://pyparsing.wikispaces.com/file/view/fourFn.py для полнофункционального калькулятора, построенного с ним.
Ответ 5
Чтобы подчеркнуть совет Дж. Ф. Себастьяна, "eval" и даже "компиляторные" решения могут быть открыты для тонких дыр в безопасности. Насколько надежным является ввод? С помощью "компилятора" вы можете, по крайней мере, отфильтровывать такие вещи, как getattr lookups из AST, но мне было проще использовать PLY или pyparsing для такого рода вещей, кроме как обеспечить результат, позволяющий получить помощь Python.
Кроме того, "компилятор" неуклюжий и трудный в использовании. Он устарел и удален в версии 3.0. Вы должны использовать модуль "ast" (добавлен в 2.6, доступен в 2.5 как "_ast" ).
Ответ 6
В согласии с vartec. Я бы использовал SymPy - в частности, функция lambdify должна делать именно то, что вы хотите.
Смотрите: http://showmedo.com/videotutorials/video?name=7200080&fromSeriesID=720
для очень приятного объяснения этого.
С наилучшими пожеланиями,
Ответ 7
Sage предназначен как замена matlab и в intro видео, он продемонстрировал, как обрабатываются похожие на ваши дела. Похоже, что они поддерживают широкий спектр подходов. Поскольку код является открытым исходным кодом, вы можете просматривать и видеть, как авторы обрабатывают такие случаи.