Comment puis-je (facilement) prendre une chaîne telle que "sin(x)*x^2"
qui pourrait être entrée par un utilisateur au moment de l'exécution et produire une fonction Python qui pourrait être évaluée pour n'importe quelle valeur de x
?
Le propre compilateur interne de Python peut analyser cela, si vous utilisez la notation Python.
Si vous modifiez légèrement la notation, vous serez plus heureux.
import compiler
eq= "sin(x)*x**2"
ast= compiler.parse( eq )
Vous obtenez un arbre de syntaxe abstrait avec lequel vous pouvez travailler.
Vous pouvez utiliser Python parser
:
import parser
formula = "sin(x)*x**2"
code = parser.expr(formula).compile()
from math import sin
x = 10
print eval(code)
Il fonctionne mieux que le pur eval
et, bien sûr, évite l'injection de code!
f = parser.parse('sin(x)*x^2').to_pyfunc()
Où parser
pourrait être défini à l'aide de PLY, de la mise en forme, du tokenizer intégré, de l'analyseur, de ast.
N'utilisez pas eval
sur les entrées utilisateur.
pyparsing peut faire ce que vous voulez ( http://pyparsing.wikispaces.com/ ) surtout si les chaînes proviennent d'une source non fiable.
Voir aussi http://pyparsing.wikispaces.com/file/view/fourFn.py pour une calculatrice assez complète construite avec elle.
Pour souligner les conseils de J.F. Sebastian, les solutions 'eval' et même 'compiler' peuvent être ouvertes à de subtiles failles de sécurité. Quelle est la fiabilité de l'entrée? Avec le `` compilateur '', vous pouvez au moins filtrer des choses comme les recherches getattr de l'AST, mais j'ai trouvé qu'il est plus facile d'utiliser PLY ou le pyparsing pour ce genre de chose que de sécuriser le résultat de laisser Python aidez.
De plus, le "compilateur" est maladroit et difficile à utiliser. Il est obsolète et supprimé dans 3.0. Vous devez utiliser le module 'ast' (ajouté en 2.6, disponible en 2.5 en tant que '_ast').
En accord avec vartec. J'utiliserais SymPy - en particulier la fonction lambdify devrait faire exactement ce que vous voulez.
Voir: http://showmedo.com/videotutorials/video?name=7200080&fromSeriesID=72
pour une très belle explication de cela.
Meilleurs vœux,
Sage est destiné au remplacement de matlab et dans vidéos d'introduction il est démontré à quel point les cas similaires aux vôtres sont traités. Ils semblent soutenir un large éventail d'approches. Étant donné que le code est open-source, vous pouvez parcourir et voir par vous-même comment les auteurs traitent de tels cas.