жадно оценивая логические выражения в Python - PullRequest
3 голосов
/ 16 февраля 2010

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

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

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

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

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

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

Ответы [ 6 ]

6 голосов
/ 16 февраля 2010
(5 < x) & (x < y)

Используя битовый оператор &, вы не получите короткого замыкания (как при использовании and, or, цепочка, all / any). Короткое замыкание обычно считается желательным (fast & c), но без него не сложно обойтись, если вы действительно хотите; -).

5 голосов
/ 16 февраля 2010

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

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

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

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

5 голосов
/ 16 февраля 2010
all([5 < x, x < y])
3 голосов
/ 16 февраля 2010
>>> x = 3
>>> y > x > 5
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'y' is not defined
2 голосов
/ 16 февраля 2010

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

1 голос
/ 16 февраля 2010

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

...