Die Funktion »eval« in Python
Die Funktion »eval« wertet einen String, der ihr als Argumentwert übergeben wird, als Python -Ausdruck aus. Sie entspricht den nach außen weisenden Doppelspitzen in unserer Notation „«2 + 3»“ (d.h. „der Wert des Ausdrucks »2 + 3«“). Damit der Ausdruck nicht schon ausgewertet wird, bevor er an »eval« übergeben wird, muß er aber durch ein Zeichenfolgenobjekt repräsentiert werden – anders herum gesagt kann man mit »eval« also einen Ausdruck auswerten lassen, der einem als Zeichenfolgenobjekt vorliegt.
- Auswertung
'2 + 3'
'2 + 3'
- Auswertung
eval( '2 + 3' )
5
- Auswertung
'2 +' + ' 3'
'2 + 3'
- Protokoll
from operator import neg
neg( eval( '2 +' + ' 3' ))
-5
- Auswertung
eval( input() )
1 + 2
3
- Auswertung
eval( input() )
7 * 'e'
'eeeeeee'
- Auswertung
type( eval( input() ))
123
<class 'int'>
- Auswertung
type( eval( input() ))
'abc'
<class 'str'>
›eval‹ erlaubt es uns nun, mit den Werte eingegebener Numeralia auch rechnen zu können, obwohl ›input‹ ja immer eine Zeichenfolge zurückgibt, mit der zunächst nicht gerechnet werden kann.
- Auswertung
eval( input() )* 3
123
369
Der Typ eines Wertes wird jedoch erst bei der Ausführung eines Programms festgelegt. Das heißt, daß derselbe Ausdruck »eval( input() )«, der eben noch die Klasse ›int‹ als Typ hatte, bei einer anderen Benutzereingabe statt dessen die Klasse ›string‹ als Typ haben kann haben kann.
- Auswertung
eval( input() )* 3
'abc'
'abcabcabc'
Als Kuriosität zeigen wir noch die Eingabe »eval( input() )«:
- Auswertung
eval( input() )
eval( input() )
None
Nachteile von »eval«
Die Auswertung eines zur Laufzeit eingegebenen Ausdrucks ist gefährlich, da ein Bediener einen Ausdruck eingeben könnte, dessen Auswertung Schäden auf dem Rechner verursacht! Deswegen sollte »eval« in der Praxis nur nach Abwägung der Sicherheitsrisiken und spezieller Absicherung eingesetzt werden, wenn das Programm von jemand anders als dem Programmierer bedient werden könnte.
Außerdem erfolgt die Auswertung eines als Zeichenfolgenobjekt vorliegenden Ausdrucks wesentlich langsamer als die Auswertung eines Ausdruck, der bei sonst gleichen Umständen im Quelltext steht.
Übungsaufgaben ⃗
/ Übungsaufgabe ⃗
Schreiben Sie einen Ausdruck, bei dessen Auswertung eine Zahl eingelesen und das Doppelte dieser Zahl ausgegeben wird. (Hier kann davon ausgegangen werden, daß der Bediener stets ein Numerale zwischen »1« und »1000« eingibt.)
- Protokoll einer Auswertung des zu erstellenden Ausdrucks
20
40
/ Übungsaufgabe ⃗
Schreiben Sie einen Ausdruck, bei dessen Auswertung zwei Zahlen eingelesen werden und ihr Mittelwert ausgegeben wird. (Hier kann davon ausgegangen werden, daß der Bediener stets Numeralia zwischen »1« und »1000« eingibt.)
- Protokoll einer Auswertung des zu erstellenden Ausdrucks
20
30
25.0
Verwendungen von ›eval‹
Es war wohl Raymond Hettinger, der ›eval‹ bei der Implementation von ›namedtupel‹ (Modul »collections«) benutzte, aber inzwischen wurde dies wohl geändert. Hettinger war sich damals sicher, daß die Verwendung von ›eval‹ in diesem Fall sicher war.
Ein Beispiel für einen Aufruf von »eval« in der Standardbibliothek (Stand 2018):
turtle.py
if value in[ "True", "False", "None", "''", '""' ]:
value = eval( value )
- Suchen nach dem Text » eval(« in einem Verzeichnis und allen Unterverzeichnissen unter Windows (für «getcwd() + "/Lib"»)
findstr /LS /C:" eval(" *.*