In dem Buch, das ich über Python lese, wird weiterhin der Code verwendet eval(input('blah'))
Ich habe die Dokumentation gelesen und verstehe sie, sehe aber immer noch nicht, wie sie die input()
Funktion verändert.
Was tut es? Kann jemand erklären?
Antworten:
Mit der eval-Funktion kann ein Python-Programm Python-Code in sich selbst ausführen.
Bewertungsbeispiel (interaktive Shell):
quelle
eval()
kann auch zum Ausführen von hochdynamischem Code verwendet werden. Sie sollten sich jedoch vor der Verwendung der Sicherheits- und Leistungsrisiken voll bewusst sein.eval
und kann auch nicht das tun, was es tuteval
.eval
Abgesehen davon, dass es unsicher ist, können nicht ganze Programme wie Codepad ausgeführt werden, da nur ein einziger Ausdruck ausgewertet werden kann.eval()
interpretiert eine Zeichenfolge als Code. Der Grund, warum so viele Leute Sie davor gewarnt haben, ist, dass ein Benutzer dies als Option verwenden kann, um Code auf dem Computer auszuführen. Wenn Sie habeneval(input())
undos
importiert haben, könnte eine Person eingeben, ininput()
os.system('rm -R *')
die alle Ihre Dateien in Ihrem Home-Verzeichnis gelöscht werden. (Vorausgesetzt, Sie haben ein Unix-System). Verwendeneval()
ist eine Sicherheitslücke. Wenn Sie Zeichenfolgen in andere Formate konvertieren müssen, versuchen Sie, Dinge zu verwenden, die dies tun, wie zint()
.quelle
eval
mitinput()
ist eine Sicherheitslücke. Geben Sie keineinput()
Bewertung ein und es wird Ihnen gut gehen.eval
ist in vielen Fällen ein Sicherheitsproblem.input
der Benutzer normalerweise seine Daten von der Konsole bezieht, kann er das Programm einfach beenden undrm -R *
trotzdemViele gute Antworten hier, aber keine beschreiben die Verwendung
eval()
im Kontext seinerglobals
undlocals
kwargs, dheval(expression, globals=None, locals=None)
(siehe Dokumente füreval
hier ).Diese können verwendet werden, um die Funktionen einzuschränken, die über die
eval
Funktion verfügbar sind . Wenn Sie beispielsweise einen neuen Python-Interpreter laden, ist derlocals()
undglobals()
derselbe und sieht ungefähr so aus:Es gibt sicherlich Funktionen innerhalb des
builtins
Moduls, die einem System erheblichen Schaden zufügen können. Aber es ist möglich, alles zu blockieren, was wir nicht zur Verfügung haben wollen. Nehmen wir ein Beispiel. Angenommen, wir möchten eine Liste erstellen, die eine Domäne der verfügbaren Kerne auf einem System darstellt. Für mich habe ich 8 Kerne, also würde ich eine Liste wollen[1, 8]
.Ebenso ist alles
__builtins__
verfügbar.OK. Dort sehen wir also eine Funktion, die wir verfügbar machen möchten, und ein Beispiel für eine (von vielen, die viel komplexer sein können) Methode, die wir nicht verfügbar machen möchten. Also lasst uns alles blockieren.
Wir haben alle
__builtins__
Funktionen effektiv blockiert und damit ein gewisses Maß an Schutz in unser System gebracht. An diesem Punkt können wir beginnen, Funktionen wieder hinzuzufügen, die verfügbar gemacht werden sollen.Jetzt haben wir die
cpu_count
Funktion zur Verfügung, während wir immer noch alles blockieren, was wir nicht wollen. Meiner Meinung nach ist dies sehr mächtig und eindeutig aus dem Umfang der anderen Antworten, keine gemeinsame Implementierung. Es gibt zahlreiche Verwendungsmöglichkeiten für so etwas und solange es richtig gehandhabt wird,eval
kann es meiner Meinung nach sicher zu einem guten Preis verwendet werden.NB
Etwas anderes Cooles an diesen
kwargs
ist, dass Sie anfangen können, Kurzschrift für Ihren Code zu verwenden. Angenommen, Sie verwenden eval als Teil einer Pipeline, um importierten Text auszuführen. Der Text muss keinen genauen Code enthalten, kann einem bestimmten Vorlagendateiformat folgen und dennoch alles ausführen, was Sie möchten. Zum Beispiel:quelle
In Python 2.x
input(...)
ist gleichbedeutend miteval(raw_input(...))
, in Python 3.xraw_input
wurde umbenanntinput
, was meiner Meinung nach zu Ihrer Verwirrung führte (Sie haben sich wahrscheinlich die Dokumentationinput
in Python 2.x angesehen). Darüber hinauseval(input(...))
würde in Python 3.x gut funktionieren , würde aberTypeError
in Python 2 ein auslösen.In diesem Fall
eval
wird verwendet, um die zurückgegebene Zeichenfolgeinput
in einen Ausdruck zu zwingen und zu interpretieren. Im Allgemeinen wird dies als schlechte Praxis angesehen.quelle
input
bedeutet, wasraw_input
in 2.x getan hat.Vielleicht ein irreführendes Beispiel dafür, wie man eine Zeile liest und interpretiert.
Versuchen Sie
eval(input())
und tippen Sie"1+1"
- dies sollte gedruckt werden2
. Eval wertet Ausdrücke aus.quelle
eval()
wertet die übergebene Zeichenfolge als Python-Ausdruck aus und gibt das Ergebnis zurück. Zum Beispieleval("1 + 1")
interpretiert und führt die Expression"1 + 1"
und gibt das Ergebnis (2).Ein Grund, warum Sie verwirrt sein könnten, ist, dass der von Ihnen zitierte Code eine Indirektionsebene beinhaltet. Der innere Funktionsaufruf (Eingabe) wird zuerst ausgeführt, damit der Benutzer die Eingabeaufforderung "blah" sieht. Stellen wir uns vor, sie antworten mit "1 + 1" (Anführungszeichen aus Gründen der Übersichtlichkeit, geben Sie sie beim Ausführen Ihres Programms nicht ein). Die Eingabefunktion gibt diese Zeichenfolge zurück, die dann an die äußere Funktion (eval) übergeben wird, die die Zeichenfolge und interpretiert gibt das Ergebnis zurück (2).
Lesen Sie mehr über eval hier .
quelle
eval()
wertet, wie der Name schon sagt, das übergebene Argument aus.raw_input()
ist jetztinput()
in Python 3.x-Versionen. Das am häufigsten vorkommende Beispiel für die Verwendung voneval()
ist daher die Verwendung der Funktionalität,input()
die in der 2.x-Version von Python bereitgestellt wird. raw_input gab die vom Benutzer eingegebenen Daten als Zeichenfolge zurück, während die Eingabe den Wert der eingegebenen Daten auswertete und zurückgab.eval(input("bla bla"))
Somit wird die Funktionalität voninput()
in 2.x repliziert , dh die vom Benutzer eingegebenen Daten auszuwerten.Kurz gesagt:
eval()
wertet die an ihn übergebenen Argumente aus und gibt dahereval('1 + 1')
2 zurück.quelle
Eine nützliche Anwendung von
eval()
ist das Auswerten von Python-Ausdrücken aus Zeichenfolgen. Beispiel: Laden aus der Dateistringdarstellung des Wörterbuchs:Lesen Sie es als Variable vor und bearbeiten Sie es:
Ausgabe:
quelle
eval
?Ich bin spät dran, um diese Frage zu beantworten, aber niemand scheint eine klare Antwort auf die Frage zu geben.
Wenn ein Benutzer einen numerischen Wert eingibt,
input()
wird eine Zeichenfolge zurückgegeben.So
eval()
wertet zurückgegebene Wert (oder Ausdruck) , die ein String und Rückkehr integer / float ist.Natürlich ist dies eine schlechte Praxis.
int()
oderfloat()
sollte anstelle voneval()
in diesem Fall verwendet werden.quelle
Eine andere Option, wenn Sie die Auswertungszeichenfolge auf einfache Literale beschränken möchten, ist die Verwendung
ast.literal_eval()
. Einige Beispiele:Aus den Dokumenten :
Warum es so begrenzt ist, aus der Mailingliste :
quelle
ast.literal_eval
unterstützt entgegen Ihrem'1+1'
Beispiel keine Operatoren . Trotzdem unterstützt es Listen, Zahlen, Zeichenfolgen usw. und ist daher eine gute Alternative für gängigeeval
Anwendungsfälle.