2016-06-22 14 views
0

Ich habe Bedingungen innerhalb von Zeichenfolgen (in Python-Bedingung Notation), z. wie folgt:Python: Intelligente Bewertung der Bedingungen

my_str = "0 and (not (1 and 0) or B_undefined_variable)" 

Ich möchte das Zustandsergebnis berechnen (in einem mathematischen Sinne). Ich benutze eval (Keine Sorge, ich weiß, es ist böse ;-)).

my_result = eval(my_str) 

Ich fand heraus, es funktioniert auch, wenn B als Brief verwendet wird, ohne als eine Variable definiert wird, weil 0 and ANYTHING immer falsch ist.

Nun, wenn ich es andersherum:

eval("Some_Undefined_Var and 0") 

es nicht mehr funktioniert. Eval scheint also eine NameError-Exception auszulösen, ohne die TRYING zu beenden, um die ganze Gleichung zu analysieren.

Kennen Sie ein beliebiges Modul/Bibliothek in Python, das versucht, solche Bedingungen zu lösen?

Danke!


Vielen Dank für Ihre Antworten. Es scheint, ich habe es nicht sehr gut erklärt. Ich möchte nicht False im Falle eines NameError zurückgeben - Ich möchte die Bedingung ausgewertet werden, wenn es bewertet werden könnte. Und tatsächlich könnte es, egal ob die Variable definiert ist oder nicht.

Es sollte in einem mathematischen Sinne berechnet werden, d. H. 0 *and* ANYTHING wird IMMER falsch sein. Das gleiche gilt für 1 *OR* ANYTHING -> WIRD IMMER WAHR ergeben, egal was ..

Und ich möchte es für umgekehrte Bedingungen arbeiten lassen. Sie würden als Mensch auch sagen, dass NO_MATTER_WHAT && 0 0 ergibt. Auch wenn der Parser sofort beendet wird, nachdem NO_MATTER_WHAT nicht definiert wurde ...

+0

Die LHS des Ausdrucks wird zuerst aufgrund von SCE ausgewertet. So wird es zurückgegeben 'NameError' –

+0

Ich denke, das ist, wie Compiler .. Interpreter funktionieren sollte .. dh eine NameError-Exception auslösen, ohne zu versuchen, die Analyse zu beenden –

+0

Wie Ändern der Zeichenfolge, so dass der Code in der Zeichenfolge überprüft, ob die Variable existiert vor dem Versuch, die Variable auszuwerten, zB 'eval (" ('foo' in local() oder 'foo' in globals()) und foo und 0 ")'? –

Antwort

1

Wenn Sie die Gefahren von eval verstehen und nur einen speziellen Wert (zB 9999) für nicht definierte Variablen, was Sie tun können, ist das Wörterbuch von eval verwendet Customizing:

import collections 
d = collections.defaultdict(lambda : 9999) 
d['x'] = 21 
d['y'] = 2 
print(eval('x * y', {}, d)) # ==> 42 
print(eval('z', {}, d))  # ==> 9999 

die einzige andere Alternative, die ich zu ist denken kann, einen Parser für Ausdrücke zu implementieren, die die and Logik verwendet Sie suchen: keine große Sache, aber ich würde sagen, es erfordert ein paar Dutzend Zeilen Code.

+0

Ich denke, das ist richtig, aber brauchen Sie nicht 'eval ('z', {}, d)', damit es funktioniert? –

+0

@PaulHankin: whoops ... sorry, danke für die heads-up – 6502

+0

Ich bin nicht sicher, dass es gültig ist, 'd' für globals in eval zu verwenden (deshalb schlug ich' eval ('z', {}, d) vor) '- Die Dokumente sagen, dass es ein Wörterbuch sein muss (während Einheimische" jedes Mapping-Objekt "sein können). Aber ich weiß nicht, ob ein Standarddict als Wörterbuch zählt. –