“或”运算符不返回布尔值的动机是什么?

新手上路,请多包涵

一、代码:

 >>> False or 'hello'
'hello'

这种令人惊讶的行为让您检查 x 是否不是 None 并在一行中检查 x 的值:

 >>> x = 10 if randint(0,2) == 1 else None
>>> (x or 0) > 0
# depend on x value...

说明: or 功能 如下

如果 x 为假,则为 y,否则为 x

我所知道的任何语言都不允许您这样做。那么,为什么Python呢?

原文由 mclafee 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 401
1 个回答

听起来您正在将两个问题合二为一。

首先,存在短路问题。 Marcin 的回答完美地解决了这个问题,所以我不会尝试做得更好。

其次,有 orand 返回最后计算的值,而不是将其转换为 bool。两种方式都有争论,你可以在分歧的两边找到许多语言。

Returning the last-evaluated value allows the functionCall(x) or defaultValue shortcut, avoids a possibly wasteful conversion (why convert an int 2 into a bool 1 如果你唯一要做的就是检查它是否非零?),并且通常更容易解释。因此,由于这些原因的各种组合,C、Lisp、Javascript、Lua、Perl、Ruby 和 VB 等语言都以这种方式做事,Python 也是如此。

始终从运算符返回布尔值有助于捕获一些错误(尤其是在逻辑运算符和按位运算符容易混淆的语言中),并且它允许您设计一种语言,其中布尔检查是严格类型检查 true 不只是检查非零,它使运算符的类型更容易写出,并且避免了在两个操作数是不同类型的情况下处理转换(参见 ?: C 系列语言中的运算符)。因此,由于这些原因的各种组合,像 C++、Fortran、Smalltalk 和 Haskell 这样的语言都以这种方式做事。


在您的问题中(如果我理解正确的话),您正在使用此功能来编写如下内容:

 if (x or 0) < 1:

x 很容易成为 None 。这个特定的用例不是很有用,因为更明确的 x if x else 0 (在 Python 2.5 及更高版本中)同样易于编写并且可能更容易理解(至少 Guido 这么认为),但是也因为 None < 10 < 1 相同(至少在 Python 2.x 中,所以你总是至少有两个选项之一)……但是有类似的例子它在 哪里 有用。比较这两个:

 return launchMissiles() or -1

return launchMissiles() if launchMissiles() else -1

第二个会浪费大量导弹,两次而不是一次炸毁你在南极洲的敌人。


如果你很好奇为什么 Python 这样做:

在 1.x 时代, 没有 bool 类型。 You’ve got falsy values like None , 0 , [] , () , "" , etc.,其他一切都是真的,所以谁需要明确 FalseTrue ? Returning 1 from or would have been silly, because 1 is no more true than [1, 2, 3] or "dsfsdf" .到添加 bool 时(逐渐超过两个 2.x 版本,IIRC),当前逻辑已经牢固地嵌入到语言中,更改会破坏很多代码。

那么,为什么他们不在 3.0 中更改它呢?许多 Python 用户,包括 BDFL Guido,会建议您在这种情况下不应该使用 or (至少因为它违反了“TOOWTDI”);您应该将表达式的结果存储在变量中,例如:

 missiles = launchMissiles()
return missiles if missiles else -1

事实上,Guido 已经表示他想禁止 launchMissiles() or -1 ,这也是他最终接受三元表达式 if - else 表达式的部分原因他之前拒绝过很多次。但很多人不同意,Guido 是一个 仁慈 的 DFL。此外,使 or 以您在其他任何地方所期望的方式工作,同时拒绝在这里做您想做的事(但 Guido 不希望您做),实际上会非常复杂。


因此,在这里,Python 可能永远与 C、Perl 和 Lisp 站在同一边,而不是与 Java、Smalltalk 和 Haskell 站在同一边。

原文由 abarnert 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题