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?

311voto

BYS2 Punkte 5129

Mit der eval-Funktion kann ein Python-Programm Python-Code in sich selbst ausführen.

eval Beispiel (interaktive Shell):

>>> x = 1
>>> eval('x + 1')
2
>>> eval('x')
1

181voto

CoffeeRain Punkte 4374

eval() interpretiert eine Zeichenkette als Code. Der Grund, warum so viele Leute Sie vor der Verwendung dieses Codes gewarnt haben, ist, dass ein Benutzer dies als Option zur Ausführung von Code auf dem Computer verwenden kann. Wenn Sie eval(input()) y os importiert, könnte eine Person Folgendes eingeben input() os.system('rm -R *') was alle Ihre Dateien in Ihrem Heimatverzeichnis löschen würde. (Vorausgesetzt, Sie haben ein Unix-System). verwenden eval() ist eine Sicherheitslücke. Wenn Sie Zeichenketten in andere Formate konvertieren müssen, versuchen Sie, Dinge zu verwenden, die das können, wie int() .

73voto

Grr Punkte 14339

Wie beschrieben in der Dokumentation , eval() hat auch globals y locals Schlüsselwortargumente, die verwendet werden können, um die Funktionen einzuschränken, die über den eval Funktion. Wenn Sie zum Beispiel einen neuen Python-Interpreter laden, wird die locals() y globals() werden gleich sein und in etwa so aussehen:

>>> globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
 '__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
 '__package__': None, '__name__': '__main__'}

Es gibt sicherlich Funktionen innerhalb der builtins Modul, das einem System erheblichen Schaden zufügen kann. Aber es ist möglich, alles zu blockieren, was wir nicht haben wollen. Nehmen wir an, wir wollen eine Liste erstellen, die eine Domäne der verfügbaren Kerne auf einem System darstellt. In meinem Fall habe ich 8 Kerne, also würde ich eine Liste wollen [1, 8] .

>>> from os import cpu_count
>>> eval('[1, cpu_count()]')
[1, 8]

Ebenso werden alle __builtins__ ist verfügbar.

>>> eval('abs(-1)')
1

Versuchen wir, den Zugriff auf alle Globals zu blockieren:

>>> eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable

Wir haben praktisch alle __builtins__ Funktionen und brachte so ein gewisses Maß an Schutz in unser System. Jetzt können wir damit beginnen, die Funktionen, die wir offenlegen wollen, wieder hinzuzufügen.

>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable

Jetzt haben wir die cpu_count Funktion zur Verfügung und blockiert dennoch alles, was wir nicht wollen. Meiner Meinung nach ist dies super mächtig und eindeutig aus dem Rahmen der anderen Antworten, nicht eine gemeinsame Umsetzung. Es gibt zahlreiche Verwendungsmöglichkeiten für so etwas, und solange es richtig gehandhabt wird, bin ich persönlich der Meinung eval kann sicher und mit großem Nutzen eingesetzt werden.

N.B..

Noch etwas anderes ist cool an diesen kwargs ist, dass Sie beginnen können, eine Kurzschrift für Ihren Code zu verwenden. Nehmen wir an, Sie verwenden eval als Teil einer Pipeline, um einen importierten Text auszuführen. Der Text muss keinen exakten Code haben, er kann einem Schablonen-Dateiformat folgen und trotzdem alles ausführen, was Sie möchten. Zum Beispiel:

>>> from os import cpu_count
>>> eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]

29voto

zeekay Punkte 49550

In Python 2.x input(...) ist gleichbedeutend mit eval(raw_input(...)) in Python 3.x raw_input wurde umbenannt in input was vermutlich zu Ihrer Verwirrung geführt hat (Sie haben sich wahrscheinlich die Dokumentation für input in Python 2.x). Zusätzlich, eval(input(...)) würde in Python 3.x gut funktionieren, würde aber ein TypeError in Python 2.

In diesem Fall eval wird verwendet, um die Zeichenkette zu erzwingen, die von input in einen Ausdruck umgewandelt und interpretiert. Dies wird im Allgemeinen als schlechte Praxis angesehen.

7voto

Rubal Punkte 936

eval() wertet, wie der Name schon sagt, das übergebene Argument aus.

raw_input() ist jetzt input() in Python 3.x Versionen. Das am häufigsten anzutreffende Beispiel für die Verwendung von eval() ist seine Verwendung zur Bereitstellung der Funktionen, die input() in der Version 2.x von Python bereitgestellt. raw_input gab die vom Benutzer eingegebenen Daten als String zurück, während input den Wert der eingegebenen Daten auswertete und zurückgab.

eval(input("bla bla")) repliziert somit die Funktionalität von input() in 2.x, d.h. der Auswertung der vom Benutzer eingegebenen Daten.

Kurz gesagt: eval() wertet die ihm übergebenen Argumente aus und somit eval('1 + 1') zurückgegeben 2.

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