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.