热切地评估Python中的布尔表达式

时间:2010-02-16 06:19:38

标签: python exception-handling lazy-evaluation eager

有没有办法(使用eval或其他)来评估python中急切的布尔表达式?

让我们看看:

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

糟糕!这非常好,因为无论y的值如何,这都是假的。问题是,y甚至可以是未定义的,我想得到那个例外。即使事先知道结果,我怎样才能让python评估所有表达式?

希望我明白了!谢谢,
曼努埃尔

编辑:请注意,不得修改表达式,只需修改评估技巧。

6 个答案:

答案 0 :(得分:6)

(5 < x) & (x < y)

通过使用位操作符&,您不会遇到短路行为(正如andor,链接,all / { {1}})。短路通常被认为是可取的(快速&amp; c)但如果你真的想要它就不难做到; - )。

答案 1 :(得分:5)

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

答案 2 :(得分:5)

最自然的方式可能是评估先前行的表达式。

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

all([5 < x, x < y])之类的解决方案隐藏副作用很重要,使用按位和(&)的解决方案看起来很微妙和误用 - 这两个都需要在代码中注释以使其显而易见正在强迫进行评估,并会让人们阅读你的代码来思考他在想什么?。将重要的计算放在他们自己的行上比将它们隐藏在微妙的,一目了然的丑陋代码中更有意义。

虽然我的解决方案无法阻止NameError如果b不存在(即您有拼写错误)并且a为假,那么您应该能够通过阅读你的代码并使用bugfinder来解决问题。

答案 3 :(得分:3)

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

答案 4 :(得分:2)

如果你想要排除程序员错误的可能性,那么急切地评估表达式就不会有太大作用。例如,将无法检测到错误地执行x or y()而不是x() or y()。也许您实际上在寻找pylintpyflakespychecker等工具。

答案 5 :(得分:1)

如果您收到来自用户的声明并希望使用您自己的语义执行该声明,则应使用pyparsing等工具自行解析。在你的中间评估别人的代码是混乱和不安全的,将他们的结果与你的结果混合在一起,评估看起来像Python代码但具有不同语义的东西是令人困惑的。