Reputation: 10186
I have conditions within strings (in python condition notation), e.g. like so:
my_str = "0 and (not (1 and 0) or B_undefined_variable)"
I want to compute the condition result (In a mathematical sense). I'm using eval
(No worries I know it is evil ;-)).
my_result = eval(my_str)
I found out, it even works when B is used as a letter without being defined as a variable, because 0 and ANYTHING
is always False.
Now when I do it the other way round:
eval("Some_Undefined_Var and 0")
it stops working. So eval seems to raise a NameError-Exception without TRYING to finish parsing the whole equation.
Do you know of ANY module / library in Python which does try to solve such conditions?
Thanks!
Thanks for your answers. It seems I didn't explain it very well. I don't want to return False in case of a NameError - I want the condition to be evaluated if it COULD be evaluated. And indeed, it could, no matter whether the variable is defined or not.
It should be computed in a mathematical sense, i.e. 0 *and* ANYTHING
will ALWAYS be False. The same applies for 1 *OR* ANYTHING
--> Will ALWAYS yield TRUE, no matter what..
And I'd like to make it work for reverted conditions as well. You, as a human would also say, that NO_MATTER_WHAT && 0
gives 0. Even though the parser would immediately quit after seeing NO_MATTER_WHAT
is not defined...
Upvotes: 0
Views: 1911
Reputation: 114579
If you understand the dangers of eval
and just want to return a special value (e.g. 9999) for undefined variables what you can do is customizing the dictionary used by eval
:
import collections
d = collections.defaultdict(lambda : 9999)
d['x'] = 21
d['y'] = 2
print(eval('x * y', {}, d)) # ==> 42
print(eval('z', {}, d)) # ==> 9999
the only other alternative I can think to is to implement a parser for expressions that uses the and
logic you are looking for: not a big deal but I'd say it requires a few tens of lines of code.
Upvotes: 1