【问题标题】:Why there is no early termination in bitwise operations?为什么按位运算没有提前终止?
【发布时间】:2014-01-28 23:06:09
【问题描述】:
def func():
    print 'no early termination'
    return 0

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

输出:

finished

因为 "1 or func()" 提前终止而不调用 func() 因为 "1 or something" 总是为真。 但是,当切换到按位运算符时:

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

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

我得到了输出:

no early termination
finished

这是为什么呢?这似乎不是很有效

【问题讨论】:

  • 因为一般来说,没有有意义的方法来短路按位运算符。因此,这就是语言行为的定义方式。
  • “位或”和“逻辑或”听起来很相似,并且具有相似的运算符(在某些语言中),但它们是非常不同的运算。
  • 按位运算的结果是算术的,不是布尔的。
  • 短路并不总是更有效,因为它相当于条件跳转。跳转可能会导致管道被刷新,代价相当高。

标签: python bit-manipulation


【解决方案1】:

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

x = 1 | 2

如果不知道右边有一个2,就无法确定x的值。

如果我们只关心 if 分支是否被占用,Python 或许可以分析程序的结构并优化掉 func 调用,但 func 的副作用必须发生在程序是正确的。 Python 无法判断打印'no early termination' 是否对您很重要;据它所知,这是确保死者的开关不会释放神经毒素的信号。

func 的副作用不会出现在 or 上,这很好,因为 or 是专门为此设计的。使用 or 告诉程序你不想要右手如果左侧为真,则评估侧边。)

【讨论】:

  • 是的,但我们可以从1 | x 知道,对于任何值x1 | x 都是真实的。 OP 的问题是有道理的。
  • @zvisofer:查看扩展答案。
  • @user2357112 这真的没有意义,因为同样的问题出现在1 or func(x) 但Python 短路并且无法运行func(x)
  • @adsmith:这有点切题,但你错了,你可以从1 | x 知道bool(1 | x) 是真的。毕竟x 可以覆盖|,所以你必须建议| 会与一些内置类型短路,但不是在所有情况下,这意味着你至少必须查看无论如何,第二个对象的类型。
  • 是的。即使bool(1 | x) 总是True,如果| 永远不会短路,它就是Least Astonishing。有时它在其中只是在布尔上下文中的世界是一个奇怪的混乱世界。
【解决方案2】:

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

类似说

if (1 + 3)

也可以这么简单

if (1 - 3)

带有逻辑运算。

【讨论】:

    【解决方案3】:

    您无法短路按位运算,因为它们没有返回简单的真值。考虑3 or 433|4 是7。如果不完全评估表达式,您将无法获得正确的按位结果。

    【讨论】:

      【解决方案4】:

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

      if 1 or func():
          print 'finished'
      

      可以改写:

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

      相比之下,按位运算符的每一边都是一个 int,结果也是如此,然后在条件评估之前隐式转换为布尔值。只有一个布尔表达式,因此无需短路。

      【讨论】:

        猜你喜欢
        • 2016-07-09
        • 1970-01-01
        • 2018-08-03
        • 2023-04-06
        • 2019-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-20
        相关资源
        最近更新 更多