Es gibt eine eval()
Funktion in Python, über die ich beim Spielen stolperte. Ich kann mir keinen Fall vorstellen, wenn diese Funktion benötigt wird, außer vielleicht als syntaktischer Zucker. Kann jemand ein Beispiel geben?Verwendung von Eval in Python?
Antwort
eval
und exec
sind handlich quick-and-dirty Weg, um einige Quellcode dynamisch zu bekommen, ist es vielleicht ein bisschen munge und dann ausführen - aber sie sind so gut wie nie die beste Art und Weise, vor allem in der Produktion Code im Gegensatz zu "schnell und schmutzig" Prototypen & c.
Zum Beispiel, wenn ich mit einem solchen dynamischen Python Quellen zu tun habe, die ich für das ast Modul erreichen würde - ast.literal_eval
ist viel sicherer als eval
(Sie können es auf einer String-Form des Ausdrucks direkt anrufen, wenn es eine einmalige und nur auf einfache Konstanten, oder tun Sie zuerst node = ast.parse(source)
, dann halten Sie die node
herum, vielleicht munge es mit geeigneten Besuchern zB für Variablen Lookup, dann literal_eval
der Knoten) - oder, einmal den Knoten in die richtige Form gebracht und überprüft es für Sicherheitsfragen, konnte ich compile
es (wodurch ein Code-Objekt) und bauen ein neues Funktionsobjekt daraus. Viel weniger einfach (außer dass ast.literal_eval
ist so einfach wie eval
für die einfachsten Fälle!), Aber sicherer und in Produktionsqualität Code vorzuziehen.
Für viele Aufgaben, die ich habe Menschen (ab-) exec
und eval
für Python leistungsstarke Einbauten, wie getattr
und setattr
, Indexieren in globals()
, & c, bieten bevorzugt und in der Tat oft einfachere Lösungen verwenden gesehen. Für bestimmte Anwendungen wie das Analysieren von JSON sind Bibliotheksmodule wie json
besser (z. B. SilentGhosts Kommentar zu Tinnitus 'Antwort auf diese Frage). Etc, etc ...
Die Wikipedia article on eval
ist ziemlich informativ und Details verschiedene Anwendungen.
Einige der Anwendungen es schon sagt, sind:
- (sind diese sehr geeignet dynamische Sprachen im Allgemeinen) mathematische Ausdrücke
- Compiler bootstrapping
- Scripting Auswertung
- Sprache Tutoren
Ich habe diesen Artikel angeschaut und verstehe immer noch nicht ... Das ist eher wie eine Rechenfunktion, die einen arithmetischen Ausdruck berechnet! – ooboo
@ooboo: 'eval' kann * irgendeinen * Code in der Theorie ausführen (daher die Sicherheitsrisiken, auf die im Artikel hingewiesen wird). – Noldorin
eval()
ist normalerweise nicht sehr nützlich. Eines der wenigen Dinge, für die ich es verwendet habe (nun, es war tatsächlich exec()
, aber es ist ziemlich ähnlich) erlaubte dem Benutzer, eine Anwendung zu skripten, die ich in Python geschrieben hatte. Wenn es in etwas wie C++ geschrieben wäre, müsste ich einen Python-Interpreter in die Anwendung einbetten.
In einem Programm, das ich einmal geschrieben, Sie hatten eine Eingabedatei in dem Sie geometrische Parameter sowohl als Wert und als Python-Ausdrücke der vorherigen Werte, zum Beispiel angeben könnten:
a=10.0
b=5.0
c=math.log10(a/b)
ein Python-Parser lesen Sie diese Eingabedatei und erhielt die endgültigen Daten, die die Werte und Ausdrücke mit eval() auswerten.
Ich behaupte nicht, dass es eine gute Programmierung ist, aber ich musste keinen Atomreaktor fahren.
In der Vergangenheit habe ich eval() verwendet, um eine Debugging-Schnittstelle zu meiner Anwendung hinzuzufügen. Ich habe einen Telnet-Dienst erstellt, der Sie in die Umgebung der ausgeführten Anwendung versetzt hat. Eingaben wurden über eval() ausgeführt, sodass Sie Python-Befehle interaktiv in der Anwendung ausführen können.
Ich habe ähnliche Scripting der COM-Schnittstelle zu Enterprise Architect, um verschiedene Abfragen ausprobieren –
Sie wollen, es benutzen können Benutzer ihre eigenen „Scriptlets“ eingeben: kleine Ausdrücke (oder sogar kleine Funktionen), die verwendet werden können, um das Verhalten eines komplexen System anpassen.
In diesem Kontext und wenn Sie sich nicht zu sehr um die Sicherheitsimplikationen kümmern müssen (z. B. haben Sie eine gut ausgebildete Benutzerdatenbank), dann ist eval() möglicherweise eine gute Wahl.
Eval ist eine Möglichkeit, mit dem Python-Interpreter aus einem Programm heraus zu interagieren. Sie können Literale an eval übergeben und sie als Python-Ausdrücke auswerten.
Zum Beispiel -
print eval("__import__('os').getcwd()")
würde das aktuelle Arbeitsverzeichnis zurück.
prost
nette Idee auch :) – securecurve
Ich benutze es als ein schneller JSON-Parser ...
r='''
{
"glossary": {
"title": "example glossary"
}
}
'''
print eval(r)['glossary']['title']
tun Sie es nicht. 'eval (" "{" Glossar ": {" death ": false}}" "") '->' NameError: Name 'false' ist nicht definiert' – SilentGhost
@SilentGhost: das ist ein toller Punkt, ich habe habe dein Beispiel in einer Antwort auf eine Frage verwendet; http://stackoverflow.com/questions/1083250/running-json-through-pythons-eval/1083302 – Kiv
Die Verwendung eines * real * JSON Parser wäre weniger fehleranfällig und sicherer. –
Ich benutze exec
, um ein System von Plugins in Python zu erstellen.
try: exec ("from " + plugin_name + " import Plugin") myplugin = Plugin(module_options, config=config) except ImportError, message: fatal ("No such module " + plugin_name + \ " (or no Plugin constructor) in my Python path: " + str(message)) except Exception: fatal ("Module " + plugin_name + " cannot be loaded: " + \ str(sys.exc_type) + ": " + str(sys.exc_value) + \ ".\n May be a missing or erroneous option?")
Mit einem Plugin wie:
class Plugin: def __init__ (self): pass def query(self, arg): ...
können Sie es nennen mag:
result = myplugin.query("something")
Ich glaube nicht, Sie Plugins in Python ohne exec
/eval
haben.
Das ist nicht gut. Sie sollten die eingebaute Funktion '__import__' verwenden, die durch die Anweisung 'from ... import ...' aufgerufen wird. – gahooa
Ich benutzte es zur Eingabe von Variablenwerten in das Hauptprogramm:
test.py var1 = 2 var2 = True
...
var1=0
var2=False
for arg in sys.argv[1:]:
exec(arg)
Eine grobe Art und Weise Stichwort args zu ermöglichen im Hauptprogramm. Wenn es einen besseren Weg gibt, lass es mich wissen!
eval() ist für einen einzelnen Satz, während exec() für mehrere ist.
normalerweise verwenden wir sie, um einige Skripts hinzuzufügen oder zu besuchen, genau wie bash shell.
wegen sie einige Byte-Skripte im Speicher ausgeführt werden kann, können Sie Ihr ‚Geheimnis‘ dekodieren, wenn Sie einige wichtige Daten oder Skript haben und entpacken Sie dann alles, was Sie tun wollen.
Ich bin gerade auf eine gute Verwendung von Eval gekommen. Ich schrieb eine Testsuite für einen bestimmten Code und erstellte eine Test-Klasse, in der jede Methode getestet werden musste.Ich wollte einen Weg, damit ich alle Testmethoden ausführen kann, ohne jede Methode einzeln aufrufen zu müssen. Also habe ich etwas ziemlich Dreckiges geschrieben.
class Test:
def __init__(self, *args):
#bs
def test1(self):
#bs
def test2(self):
#bs
if __name__ == "__main__":
import argparse
#argparse bs
test = Test(*bs_args)
for func in (i for i in dir(test) if i[0] != '_' and i not in test.__dict__):
print(eval('test.{func}()'.format(func = func)))
Dynamische Auswertung von beliebigen Testfällen ist ziemlich cool. Ich muss nur die Methode schreiben, und nach dem Speichern kann ich die Methode in meine Testsuite aufnehmen. Was den Code betrifft, untersuche ich im Grunde nur die im Testobjekt definierten Methoden und stelle sicher, dass sie keine Standard-Python-Zaubermethoden oder -attribute für das Testobjekt sind. Danach kann ich davon ausgehen, dass sie Methoden sind und ausgewertet werden können.
Sie können in einem Dekorateur eval:
#this replaces the original printNumber with a lambda-function,
#which takes no arguments and which calls the old function with
#the number 10
@eval("lambda fun: lambda: fun(10)")
def printNumber(i: int) -> None:
print("The number is %i", i)
#call
printNumber()
, während Sie nicht komplexe Ausdrücke wie
@lambda fun: lambda: fun(10)
def ...
noch
@(lambda fun: lambda: fun(10))
def ...
Sie einen Lambda-Ausdruck verwenden können dort nicht verwenden können, weil der Dekorator entweder eine Kennung sein sollte:
@myModule.functionWithOneArg
oder ein Funktionsaufruf:
@functionReturningFunctionWithOneArg(any, "args")
Sie sehen, dass der Aufruf der Funktion eval mit einem String hier gültige Syntax, aber die Lambda-Ausdruck nicht. (->https://docs.python.org/3/reference/compound_stmts.html#function-definitions)
'als syntaktischer Zucker' - was bedeutet das? – jwg