343 Stimmen

Was macht Pythons eval()?

In dem Buch, das ich gerade über Python lese, wird immer wieder der Code eval(input('blah'))

Ich habe die Dokumentation gelesen und verstehe sie, aber ich verstehe immer noch nicht, wie sie die input() Funktion.

Was bewirkt es? Kann das jemand erklären?

6voto

hburde Punkte 1441

Vielleicht ein irreführendes Beispiel für das Lesen und Interpretieren einer Zeile.

Pruebe eval(input()) und tippen "1+1" - dies sollte gedruckt werden 2 . Eval wertet Ausdrücke aus.

6voto

Marc Cohen Punkte 3712

eval() wertet die übergebene Zeichenkette als Python-Ausdruck aus und gibt das Ergebnis zurück. Zum Beispiel, eval("1 + 1") interpretiert und führt den Ausdruck "1 + 1" und gibt das Ergebnis zurück (2).

Ein Grund für die Verwirrung könnte sein, dass der von Ihnen zitierte Code eine indirekte Ebene beinhaltet. Der innere Funktionsaufruf (Eingabe) wird zuerst ausgeführt, so dass der Benutzer die Eingabeaufforderung "blah" sieht. Nehmen wir an, er antwortet mit "1 + 1" (Anführungszeichen zur Verdeutlichung hinzugefügt, geben Sie sie nicht ein, wenn Sie Ihr Programm ausführen). Die Eingabefunktion gibt diese Zeichenfolge zurück, die dann an die äußere Funktion (eval) weitergegeben wird, die die Zeichenfolge interpretiert und das Ergebnis (2) zurückgibt.

Lesen Sie mehr über eval aquí .

6voto

Nikolay Frick Punkte 2019

Eine der nützlichen Anwendungen von eval() ist es, Python-Ausdrücke aus String auszuwerten. Zum Beispiel laden aus Datei String-Darstellung des Wörterbuchs:

running_params = {"Greeting":"Hello "}
fout = open("params.dat",'w')
fout.write(repr(running_params))
fout.close()

Lesen Sie sie als Variable aus und bearbeiten Sie sie:

fin = open("params.dat",'r')
diction=eval(fin.read())
diction["Greeting"]+="world"
fin.close()
print diction

Ausgabe:

{'Greeting': 'Hello world'}

6voto

Brian Burns Punkte 17530

Eine andere Möglichkeit, die Auswertungszeichenfolge auf einfache Literale zu beschränken, ist die Verwendung von ast.literal_eval() . Einige Beispiele:

import ast

# print(ast.literal_eval(''))          # SyntaxError: unexpected EOF while parsing
# print(ast.literal_eval('a'))         # ValueError: malformed node or string
# print(ast.literal_eval('import os')) # SyntaxError: invalid syntax
# print(ast.literal_eval('1+1'))       # 2: but only works due to a quirk in parser
# print(ast.literal_eval('1*1'))       # ValueError: malformed node or string
print(ast.literal_eval("{'a':1}"))     # {'a':1}

Von der docs :

Sichere Auswertung eines Ausdrucksknotens oder einer Zeichenkette, die ein Python-Literal oder eine Containeranzeige enthält. Die angegebene Zeichenkette oder der Knoten kann nur bestehen aus den folgenden Python-Literalstrukturen: Strings, Bytes, Zahlen, Tupel, Listen, Dicts, Sets, Booleans und None.

Dies kann zur sicheren Auswertung von Zeichenketten mit Python-Werten aus nicht vertrauenswürdigen Quellen verwendet werden, ohne dass die Werte selbst geparst werden müssen. Es ist no die in der Lage sind, beliebig komplexe Ausdrücke auszuwerten, z. B. unter Einbeziehung von Operatoren oder Indizierungen.

Warum sie so begrenzt ist, ist eine Frage von die Mailingliste :

Das Zulassen von Operatorausdrücken mit Literalen ist möglich, aber viel komplexer als die derzeitige Implementierung. Eine einfache Implementierung ist nicht sicher: Sie können ohne großen Aufwand eine praktisch unbegrenzte CPU- und Speichernutzung verursachen (versuchen Sie "9**9**9" oder "[None] * 9**9").

Was die Nützlichkeit angeht, so ist diese Funktion nützlich, um literalische Werte und Container, wie sie von repr() stringifiziert wurden, "zurückzulesen". Dies kann zum Beispiel für die Serialisierung in einem Format verwendet werden, das JSON ähnelt, aber leistungsfähiger ist als dieses.

5voto

Calvin Kim Punkte 191

Wenn ein Benutzer einen numerischen Wert eingibt, input() gibt eine Zeichenkette zurück.

>>> input('Enter a number: ')
Enter a number: 3
>>> '3'
>>> input('Enter a number: ')
Enter a number: 1+1
'1+1'

eval() wertet den zurückgegebenen Wert (oder Ausdruck) aus, der eine Zeichenkette ist, und gibt Integer/Float zurück.

>>> eval(input('Enter a number: '))
Enter a number: 1+1
2
>>> 
>>> eval(input('Enter a number: '))
Enter a number: 3.14
3.14

Es wäre jedoch besser, hier spezifischere Instrumente zu verwenden, wie z. B. int() o float() .

>>> float(input('Enter a number: '))
Enter a number: 3.14
3.14

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X