为什么在按位运算中没有提前终止?

时间:2014-01-28 23:06:10

标签: python bit-manipulation

def func():
    print 'no early termination'
    return 0

if __name__ == "__main__":
    if 1 or func():
        print 'finished'

输出:

finished

因为“1或func()”在没有调用func()的情况下提前终止,因为“1或者某个东西”总是为真。 但是,当切换到按位运算符时:

def func():
    print 'no early termination'
    return 0

if __name__ == "__main__":
    if 1 | func():
        print 'finished'

我得到了输出:

no early termination
finished

为什么?这看起来效率不高

4 个答案:

答案 0 :(得分:8)

|不能短路,因为它的值取决于它的右手操作数,即使它的左手操作数为真。例如,在

x = 1 | 2

如果不知道右侧有x,则无法确定2的值。

如果我们只关心是否采用if分支,Python可能能够分析程序的结构并优化掉func调用,但{{1}的副作用必须发生程序才能正确。 Python无法判断打印func对您来说是否重要;据他所知,这是确保死人的开关不会释放神经毒素的信号。

'no early termination'不会出现func的副作用,因为or是专门设计的。使用or告诉程序你如果左侧是真的,不要评估右侧。)

答案 1 :(得分:1)

这些更像是数学运算而不是逻辑运算。这就是整个表达式需要评估的原因。

这与说

相似
if (1 + 3)

它可以很容易

if (1 - 3)

使用逻辑操作。

答案 2 :(得分:1)

使用逻辑运算符,表达式的每一边都是一个可以单独计算的布尔值。即使特定语言不支持短路,也可以在没有操作员的情况下重写这样的表达式以实现相同的分支行为。例如:

if 1 or func():
    print 'finished'

可以改写:

if 1:
    pass
elif func():
    print 'finished'

相反,按位运算符的每一边都是一个int,结果也是如此,然后在被条件计算之前隐式地转换为boolean。只有一个布尔表达式,因此没有什么可以短路。

答案 3 :(得分:1)

由于它们没有返回简单的真值,因此无法使按位运算短路。请注意3 or 433|4为7.如果没有完全评估表达式,您将无法获得正确的按位结果。