听起来您将两个问题合二为一。
首先,存在短路问题。 Marcin 的回答完美地解决了这个问题,所以我不会尝试做得更好。
其次,or 和 and 返回最后评估的值,而不是将其转换为布尔值。两种方式都有争论,您可以在分歧的任何一方找到许多语言。
返回最后评估的值允许使用 functionCall(x) or defaultValue 快捷方式,避免可能的浪费转换(如果您要做的唯一事情,为什么要将 int 2 转换为 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 是这么认为的),还因为@987654334 @ 无论如何都与0 < 1 相同(至少在Python 2.x 中,所以你总是至少有两个选项之一)......但是也有类似的例子,它 很有用。比较这两个:
return launchMissiles() or -1
return launchMissiles() if launchMissiles() else -1
第二个将浪费大量导弹在南极洲炸毁你的敌人两次而不是一次。
如果你好奇 Python 为什么会这样:
在 1.x 时代,没有bool 类型。你有 None、0、[]、()、"" 等虚假值,其他一切都是真的,那么谁需要明确的 False 和 True?从or 返回1 会很愚蠢,因为1 并不比[1, 2, 3] 或"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 站在同一边。