2016-03-31 9 views
3

Ich habe versucht, Python3s ast.literal_eval() -Funktion zu arbeiten (in einer interaktiven Python-Sitzung), aber - und ich lese es ist doc Beschreibung - Ich kann nicht.Unterstützung mit Pythons ast.literal_eval ('a_string')

Mein Ziel ist es, dies zu ersetzen:

>>> import logging 
>>> eval('logging.DEBUG') 
10 

mit der sichereren Alternative, diese:

>>> import logging, ast 
>>> ast.literal_eval('logging.DEBUG') 
Traceback (most recent call last): 
... 
ValueError: malformed node or string: <_ast.Attribute object at 0x7f1ccc55eeb8> 

aber diese funktioniert nicht (zumindest nicht, wie ich es bin mit). Beachten Sie, dass ich auch versucht triple zitierte und Roh-String Variationen, auch.

Ich glaube, ich bin einfach eine Nuance hier fehlt (zum Beispiel ist es möglich, dass es keine Konstanten in einem Modul Auswertung mögen). Aus der Python-3-Dokumentation auf ast.literal_eval():

sicher einen Ausdruck Knoten oder ein Zeichenfolge enthaltend eine Python Literal oder Behälter Anzeige auszuwerten. Die angegebene Zeichenfolge oder der angegebene Knoten darf nur aus den folgenden Python-Literalstrukturen bestehen: Strings, Bytes, Zahlen, Tupel, Listen, Dicts, Mengen, Booleans und None.

Dies kann zur sicheren Auswertung Strings Python enthält, verwendet werden Werte von nicht vertrauenswürdigen Quellen, ohne die Notwendigkeit, die Werte zu analysieren sich. Es ist nicht in der Lage, beliebig komplexe Ausdrücke auszuwerten, zum Beispiel Operatoren oder Indizierung.

Jede Hilfe sehr geschätzt. = :) Vielen Dank im Voraus!

+4

Ich glaube, Sie verstehen den * wörtlichen * Teil von 'literal_eval' falsch. 'literal_eval (" 'logging.DEBUG' ")' -> ''logging.DEBUG''. Sie können nur Literale, d. H. Strings, Tupel, Dicts, Zahlen usw. auswerten und erhalten denselben Datentyp, den Sie als String-Repräsentation übergeben haben. Das ist irgendwie der Punkt. – timgeb

+0

Danke.Ich habe dieses Szenario auch versucht (gerade wegen der wörtlichen Formulierung). :). Ich schätze, ich versuche (und vielleicht ist es hier nicht möglich), die Syntax für die Verwendung von etwas sicherer als eval() zu bekommen. Früher war irgendwo ein safe_eval. Aber ich versuche das zuerst. –

+0

Ein wenig mehr Kontext: Ich verwende configparser.SafeConfigParser(), um ein k/v-Paar abzuleiten: log_level = "logging.DEBUG". Das führt natürlich zu einem Bezeichner, der auf einen String zeigt (der kein Literal ist); aber die dennoch in einen Ganzzahlwert auf Log-Ebene ausgewertet werden muss. eval() funktioniert, aber ich bevorzuge es nicht zu verwenden. Wie ich in der Post erwähnt habe, ist es hier vielleicht nicht möglich, aber ich wollte die Community fragen. :) –

Antwort

4

Mit dem Kontext Sie Kommentar geben, ich rate Ihnen, dass Sie nicht zu tun:

  • Sie nicht verwenden können ast.literal_eval weil logging.Debug kein Litteral ist: Sie stellen einen Wert aus einem Modul, und das könnte beliebig haben Nebeneffekte
  • sollten Sie eval nicht für einen Wert verwenden, der aus einer externen Datei gelesen wird.

Mein Rat eine Karte zu verwenden wäre:

log_levels = { 'DEBUG': logging.DEBUG, ... } 

Wenn Sie später log_level lesen (sagen debug) aus Ihrer Konfigurationsdatei, die Sie gerade tun:

real_level = log_levels[log_level] 

Auf diese Weise können kann problemlos Fallfehler mit real_level = log_levels[log_level.upper()] akzeptieren, und wenn es einen unerwarteten Wert in der Konfigurationsdatei gibt, erhalten Sie nur eine KeyError Ausnahme, ohne das Risiko einer unerwünschten Auswertung.

+0

Hallo dort. Wie @timgeb ursprünglich erwähnt (in seinem Kommentar), hatte ich bereits eine Debug-Level-Diktat-Implementierung (definiert in einem Modul. Es ist meine allgemeine Vorgehensweise, in der Tat). Aber wollte danach fragen. Ich schätze, ich werde zu einem Diktat zurückkehren. Ich kehre zurück, um eine Lösung zu finden, aber unterdessen habe ich Ihre Antwort und Timgebs Kommentare (beide) upvoted. Danke Jungs. –