2016-06-22 4 views
0

У меня есть условия в строках (в обозначении состояния питона), например. например:Python: Интеллектуальная оценка условий

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

Я хочу вычислить результат условия (в математическом смысле). Я использую eval (Не беспокойтесь, я знаю, что это зло ;-)).

my_result = eval(my_str) 

я узнал, он даже работает, когда B используются в качестве письма, не определяются как переменные, так как 0 and ANYTHING всегда Ложные.

Теперь, когда я делаю это наоборот:

eval("Some_Undefined_Var and 0") 

он перестает работать. Таким образом, eval, похоже, вызывает исключение NameError-Exception без TRYING, чтобы закончить синтаксический анализ всего уравнения.

Вы знаете ЛЮБОЙ модуль/библиотеку в Python, который пытается решить такие условия?

Спасибо!


Спасибо за ваши ответы. Кажется, я не очень хорошо объяснил это. Я не хочу возвращать False в случае NameError - я хочу, чтобы условие оценивалось, если оно МОЖЕТ быть оценено. И действительно, это могло бы быть, независимо от того, определена ли переменная или нет.

Его следует вычислить в математическом смысле, то есть 0 *and* ANYTHING ВСЕГДА будет ложным. То же самое относится и к 1 *OR* ANYTHING -> ВСЕГДА даст ИСТИННУЮ, независимо от того, что ..

И я бы хотел, чтобы это работало и для вернувшихся условий. Вы, как человек хотел бы также сказать, что NO_MATTER_WHAT && 0 дает 0. Даже если анализатор будет немедленно прекратить после просмотра NO_MATTER_WHAT не определен ...

+0

LHS выражения оценивается сначала из-за SCE. Таким образом, он вернет 'NameError' –

+0

. Я думаю, что это значит, что компиляторы .. интерпретаторы должны работать .. то есть поднять исключение NameError-Exception без TRYING, чтобы закончить синтаксический анализ –

+0

Как насчет модификации строки, так что код в строке проверяет, является ли переменная существует, прежде чем пытаться оценить переменную, например, 'eval (« (foo »в locals() или« foo »в globals()) и foo и 0") '? –

ответ

1

Если вы понимаете опасности eval и просто хотите вернуть специальное значение (например, 9999) для неопределенных переменных, что вы можете сделать, это настройка словаря, используемый 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 

единственной альтернативой я могу думать, чтобы это реализовать синтаксический анализатор для выражений, которые используют and логики, которую вы ищете: не большое дело, но я бы сказал, что для этого требуется несколько десятков строк кода.

+0

Я думаю, что это правильно, но вам не нужны 'eval ('z', {}, d)', чтобы заставить его работать? –

+0

@PaulHankin: whoops ... извините, спасибо за головы – 6502

+0

Я не уверен, что это правильно использовать 'd' для globals в eval (вот почему я предложил' eval ('z', {}, d) '- Документы говорят, что это должен быть словарь (тогда как locals могут быть« любым объектом сопоставления »). Но я не знаю, считается ли defaultdict словарем. –