2010-02-16 2 views
3

Есть ли способ (используя eval или что-то еще) для оценки нетерпимо булевых выражений в python?с нетерпением оценивая булевы выражения в Python

Давайте посмотрим это:

>>> x = 3 
>>> 5 < x < y 
False 

Yikes! Это очень приятно, потому что это будет ложно, независимо от значения y. Дело в том, что y может быть даже неопределенным, и я хотел бы получить это исключение. Как я могу получить python для оценки всех выражений, даже если он знает результат заранее?

Надеюсь, я поняла! Спасибо,
Manuel

Edit: Пожалуйста, имейте в виду, что выражение не должно быть изменено, только метод оценки.

+0

Все, что делает это, будет злым и ужасным. Если это так важно, явным образом оцениваю все ваши выражения и утверждаю, что они не None. –

+0

Что вы подразумеваете под «полной оценкой всех выражений»? Спасибо –

+1

-1: Для этого нет возможного варианта использования. –

ответ

5
all([5 < x, x < y]) 
+1

Нет, это тоже короткое замыкание. –

+3

@Alex: Даже при создании списка? –

+2

Нет, «все» короткие замыкания, но понимание списка очень велико (genexp - ленивый эквивалент). Итак, 'x

6
(5 < x) & (x < y) 

С помощью битов и оператора, &, вы не получаете поведение короткого замыкания (как вы получите с and, or, СЦЕПЛЕНИЕ, all/any). Короткое замыкание обычно считается желательным (быстрый & c), но без него это не сложно, если вы действительно этого хотите ;-).

+1

Я не уверен, что это лучшее решение. Если бы я прочитал это, я бы подумал: «Этот человек не знает, как использовать« и »и« и », не говоря уже о цепных операторах сравнения», а не «Оххх, тот, кто написал это, заставлял оценивать оба аргумента», за исключением, сразу после моего кофе. –

+1

Это ужасно. –

+3

Но, я полагаю, любой ответ на этот вопрос будет ужасным. –

3
 
>>> x = 3 
>>> y > x > 5 
Traceback (most recent call last): 
    File "", line 1, in 
NameError: name 'y' is not defined 
5

Наиболее естественным способом, вероятно, будет оценка выражений на предыдущих строках.

a = foo() 
b = bar() 
if a and b: 
    ... 

как решения, как all([5 < x, x < y]) скрывает, что побочные эффекты являются важными и решение с использованием побитового и (&) кажется тонким и злоупотребляя-оба они требуют бы комментария в коде, чтобы сделать это очевидно, что вы вынуждаете оценки и заставит людей читать ваш код, чтобы думать Что он думал ???. Помещение важных расчетов по их собственным линиям имеет больше смысла, чем скрытие их в тонком, на первый взгляд, уродливом коде.

Хотя мое решение не мешает NameError если b не существует (то есть, у вас есть опечатка) и a является ложным, это то, что вы должны быть в состоянии выяснить, прочитав ваш код и используя bugfinder если твой выбор.

+1

На мой взгляд, этот ответ является самым питоническим. Вы явно определяете операции, которые хотите выполнить, а затем оцениваете их. –

2

Если это просто возможность ошибки программиста, которую вы хотите исключить, то нетерпеливая оценка выражений не принесет больших результатов. Например, ошибочное выполнение x or y() вместо x() or y() не будет обнаружено. Возможно, вы действительно ищете такие инструменты, как pylint, pyflakes или pychecker.

+0

Да, но мне нужно сделать это динамически, и эти инструменты, похоже, работают как исполняемые файлы командной строки. Любая фреймворк/модуль, который вы знаете, делает то же самое, что и «str»? –

1

Если вы получаете инструкцию от пользователя и хотите выполнить ее с помощью своей собственной семантики, вы должны проанализировать ее самостоятельно с помощью такого инструмента, как pyparsing. Это грязно и небезопасно оценивать чужой код в середине вашего, смешивая их результаты с вашими, и это путать, чтобы оценить, что выглядит Python-кодом, но с другой семантикой.

Смежные вопросы