Seite 1 von 1
eval() in Variable speichern
Verfasst: Freitag 7. Mai 2010, 21:52
von classic
Hi,
Ich bin für die Schule an einem Projekt, um nichtlineare Gleichungen darzustellen.
Diese soll der Nutzer auch eingeben können.
Also lese ich diesen String der Funktion ein und "interpretiere" ihn mittels der eval-Funktion.
Also um den Funktionswerts eines Punktes zu bekommen:
Nun meine Frage:
Ist es möglich, dass ich mir anstatt den String zu speichern, dieses eval() in Abhängigkeit von x speichere (also quasi als "richtige" Funktion von x [f(x)=...]) ?
Oder hat das ständige Evaluieren (für momentan ~ 400 x-Werte) kaum Performance-Einbußen?
MfG
classic
Verfasst: Freitag 7. Mai 2010, 22:02
von Defnull
Nicht mit eval() direkt, aber mit compile() und ein paar Umwegen.
Code: Alles auswählen
>>> namespace = {}
>>> formula = 'x*5'
>>> code = compile('def func(x): return %s' % formula, '<string>', 'exec')
>>> eval(code, namespace)
>>> func = namespace.get('func')
>>> func(5)
25
>>> func(6)
30
Allerdings wird dir kein Lehrer glauben, das du das selbst heraus gefunden hast.
Und noch was für's Leben: eval() und ähnliche Dinge sind böse. Benutze sie nur, wenn du GENAU weist, was du da tust. Für Lern-Zwecke sind sie brauchbar aber in echter Software meistens Fehl am Platze oder sogar gefährlich.
Edit: Blöd das ich da nicht gleich drauf gekommen bin, es geht auch einfacher:
Code: Alles auswählen
>>> formula = 'x*5'
>>> func = eval('lambda x: %s' % formula)
>>> func(4)
20
Verfasst: Freitag 7. Mai 2010, 22:15
von classic
Ok, Dankeschön, das mit lambda ist auch nicht so unrealistisch, habe ich selbst auch schon mal verwendet
Aber warum ist eval() gefährlich?
Gibt es denn andere Möglichkeiten Formeln die der Nutzer eingibt zu interpretieren?
Man kann den String ja sicherlich auch so parsen, aber das ist wahrscheinlich ein relativ großer Aufwand, würde sich das denn so signifikant lohnen?
MfG
classic
Edit:
Noch eine Frage:
Wenn der Nutzer nun beispielsweise eine Sinuskurve will, dann muss er Math.sin(x) eingeben [Falls ich im globals-Dictionary 'math':math stehen habe], damit es klappt.
Ist es möglich, dass er nur sin(x) eingeben muss?
Verfasst: Freitag 7. Mai 2010, 22:42
von BlackJack
@classic: `eval()` ist gefährlich weil der Benutzer da beliebige Ausdrücke eingeben kann. Wenn Du dem Benutzer zum Beispiel erlaubst die Formeln auch in eine Datei zu speichern, um sie später wiederzuverwenden, könnte jemand auf die Idee kommen da "böse" Sachen zu speichern, wie zum Beispiel das Löschen aller Dateien im Heimatverzeichnis, und diese Datei dann versuchen anderen Benutzern des Programms unterzuschieben.
Zur zweiten Frage: Du musst in das Dictionary halt einfach alle Attribute vom `math`-Modul übertragen. Schau Dir mal `dir()` und `getattr()` an. Altenativ `inspect.getmembers()`.
Verfasst: Freitag 7. Mai 2010, 23:03
von classic
Ok, aber ich glaube bei unserem Schülerprojekt spielt das keine so große Rolle
Danke, das mit dir() und getattr() hat funktioniert
MfG
classic
Verfasst: Samstag 8. Mai 2010, 02:57
von ms4py
Verfasst: Samstag 8. Mai 2010, 10:54
von HerrHagen
Vielleicht ist sympy auch für dich interessant:
http://docs.sympy.org/tutorial.html
Damit kannst du auch symbolisch rechnen. Also sowas hier: