Also ich habe verstanden, was exec
und eval
und auch compile
tun. Aber warum sollte ich sie benutzen müssen? Ich bin unklar über das Nutzungsszenario.
Kann mir jemand ein paar Beispiele geben, damit ich das Konzept besser verstehen kann? Denn ich weiß, es ist alles Theorie.
Ich gebe ein Beispiel, in dem ich eval
verwendet habe und wo ich denke, dass es die beste Wahl war.
Ich habe ein einfaches Softwaretestprogramm geschrieben ... etwas, um zu testen, ob die Übungen der Schüler den Anforderungen der Aufgaben entsprechen. Das Ziel bestand darin, eine einfache Konfigurationsdatei als Testspezifikation bereitzustellen (um eine "Henne-und-Ei" -Problematik der Verwendung einer Programmiersprache zur Beschreibung / Dokumentation / Implementierung der Testfälle für elementare Programmieraufgaben zu umgehen). .
Ich habe meinen Kabelbaum auf dem ConfigParser in den Standardbibliotheken aufgebaut. Allerdings wollte ich die Möglichkeit haben, beliebige Python-Zeichenfolgen darzustellen (einschließlich der Interpolationen von \ n, \ t und insbesondere aller interpolierten hexadezimierten ASCII-Zeichen in den daraus gelesenen Werten.
Meine Lösung war ein try
um ein parsed_string=eval('''%s''' % cfg_read_item)
, gefolgt von einem try
der dreifachen doppelt zitierten Version (""% s "" ") derselben.
Dies ist ein Fall, in dem die Alternative darin bestünde, einen Python-Parser zu schreiben (oder einen vorgefertigten Python-Parser zu finden) und herauszufinden, wie man ihn in mein Programm einbinden und anpassen kann. Die Risiken sind minimal (ich mache mir keine Sorgen, dass der von Studenten eingereichte Code meinen Parser trickst, wenn er ins Gefängnis gerät, alle meine Dateien löscht, meine Kreditkartennummern nach Rumänien schickt usw.) *
* (Teilweise weil ich sie unter Linux von einem nicht vertrauenswürdigen kopflosen Benutzerkonto getestet habe).
Wie hier bereits erwähnt, gibt es andere Anwendungsfälle, in denen Sie Code aus einer Vorlage basierend auf Eingabedaten erstellen und diesen Code ausführen müssen (Metaprogrammierung). Sie sollten diese Aufgaben immer auf eine andere Weise erledigen können. Wann immer diese Alternative einen Programmieraufwand mit sich bringt, der sich dem Schreiben eines allgemeinen Programmiersprachenparsers / Compilers / Interpreters nähert, kann eval
der bessere Ansatz sein.
Die Standardbibliothek enthält ein anschauliches Beispiel für die Verwendung von exec
. collections.namedtuple verwendet es, um eine Klasse dynamisch zu erstellen .
ast
verwendet compile
, um abstrakte Syntaxbäume aus Python-Quellcode zu generieren. Diese werden von Modulen wie pyflakes
verwendet, um Python zu analysieren und zu validieren.
Sie brauchen nicht, um sie zu verwenden, und meiner Meinung nach sollten Sie sie vermeiden.
Sie sind nur in Fällen nützlich, in denen Sie den Code selbst generieren, der am Ende wahrscheinlich als schlechte Praxis angesehen wird.
Wenn Sie in Betracht ziehen, eval () für Dinge wie mathematische Ausdrücke zu verwenden, sollten Sie die Eingabe besser bereinigen, bevor Sie sie auswerten. Sie wissen nie, welche Art von "Text" der Benutzer sendet, die die Anwendung selbst vermasseln könnte.
Ich denke, ich habe eine gültige Verwendung. Ich verwende Python 3.2.1 in Blender 2.6.4, um eine Menge von Punkten mit x, y-Koordinaten (in der z-Ebene) zu ändern.
Das Ziel besteht darin, um jeden vorhandenen Punkt herum konzentrische Ringe mit neuen Punkten hinzuzufügen, wobei sich die Ringe wie Wellen verhalten (wie wenn Sie einen Stein in einen Teich fallen lassen). Der Clou ist, dass ich möchte, dass die Wellen konstruktiv / destruktiv ineinander eingreifen, also gehe ich zuerst durch und konstruiere eine "Welligkeitsgleichung", die an jedem Punkt zentriert ist, und summiere alle Welligkeitsgleichungen zu einer gigantischen mathematischen Gleichung Ich werde dann die ursprünglichen Punkte einspeisen, um den korrekten Z-Wert zu erzeugen, dem jeder zugeordnet werden kann.
Mein Plan ist es, jeden zusätzlichen Ausdruck in der Gleichung als String an den vorherigen anzuhängen und dann eval () zu verwenden, um den Z-Wert für den neuen Satz von Punkten zu berechnen.
Sie fragen nur nach einem Beispiel? Sie könnten eine einfache App schreiben, die von Standard in liest und dem Benutzer erlaubt verschiedene Ausdrücke wie (4*2)/8 - 1
einzugeben. In anderen Sprachen (Java, C ++, etc.) wäre dies fast unmöglich zu bewerten, aber in Python ist es einfach, nur:
Abgesehen davon, dass Sie vorsichtig sind, kann die Verwendung dieser Dinge sehr gefährlich sein, da sie (im Wesentlichen) dem Benutzer eine große Menge an Zugriff ermöglichen.
Dies wird in der Meta-Programmierung verwendet (wenn das Programm selbst schreibt). Zum Beispiel haben Sie Tiere verschiedener Arten, die mit verschiedenen Klassen beschrieben werden: Löwe, Tiger, Pferd, Esel. Und Sie wollen die Kreuzung zwischen ihnen simulieren, zum Beispiel zwischen Löwen und Tiger. Wenn Sie das Programm schreiben, können Sie nicht bestimmen, wie der Benutzer die Tiere durchqueren wird, aber Sie können im Handumdrehen neue Tierklassen erstellen:
%Vor%P. Sorry, ich habe Python vergessen. Also gibt es eine Menge Pseudo-Code.
Hier ist ein gültiger Anwendungsfall. In der Python-Paste-Middleware (für Web-Programmierung) erzeugt eine Exception eine Befehlszeile innerhalb des Browsers. Dies funktioniert mit Methoden wie diesen. In Blender gibt es auch eine Option, um Werte mithilfe von Python-Ausdrücken zu animieren. Dies funktioniert mit eval.