一、代码:
>>> 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 许可协议
听起来您正在将两个问题合二为一。
首先,存在短路问题。 Marcin 的回答完美地解决了这个问题,所以我不会尝试做得更好。
其次,有
or
和and
返回最后计算的值,而不是将其转换为 bool。两种方式都有争论,你可以在分歧的两边找到许多语言。Returning the last-evaluated value allows the
functionCall(x) or defaultValue
shortcut, avoids a possibly wasteful conversion (why convert anint
2
into abool
1
如果你唯一要做的就是检查它是否非零?),并且通常更容易解释。因此,由于这些原因的各种组合,C、Lisp、Javascript、Lua、Perl、Ruby 和 VB 等语言都以这种方式做事,Python 也是如此。始终从运算符返回布尔值有助于捕获一些错误(尤其是在逻辑运算符和按位运算符容易混淆的语言中),并且它允许您设计一种语言,其中布尔检查是严格类型检查
true
不只是检查非零,它使运算符的类型更容易写出,并且避免了在两个操作数是不同类型的情况下处理转换(参见?:
C 系列语言中的运算符)。因此,由于这些原因的各种组合,像 C++、Fortran、Smalltalk 和 Haskell 这样的语言都以这种方式做事。在您的问题中(如果我理解正确的话),您正在使用此功能来编写如下内容:
当
x
很容易成为None
。这个特定的用例不是很有用,因为更明确的x if x else 0
(在 Python 2.5 及更高版本中)同样易于编写并且可能更容易理解(至少 Guido 这么认为),但是也因为None < 1
与0 < 1
相同(至少在 Python 2.x 中,所以你总是至少有两个选项之一)……但是有类似的例子它在 哪里 有用。比较这两个:第二个会浪费大量导弹,两次而不是一次炸毁你在南极洲的敌人。
如果你很好奇为什么 Python 这样做:
在 1.x 时代, 没有
bool
类型。 You’ve got falsy values likeNone
,0
,[]
,()
,""
, etc.,其他一切都是真的,所以谁需要明确False
和True
? Returning1
fromor
would have been silly, because1
is no more true than[1, 2, 3]
or"dsfsdf"
.到添加bool
时(逐渐超过两个 2.x 版本,IIRC),当前逻辑已经牢固地嵌入到语言中,更改会破坏很多代码。那么,为什么他们不在 3.0 中更改它呢?许多 Python 用户,包括 BDFL Guido,会建议您在这种情况下不应该使用
or
(至少因为它违反了“TOOWTDI”);您应该将表达式的结果存储在变量中,例如:事实上,Guido 已经表示他想禁止
launchMissiles() or -1
,这也是他最终接受三元表达式if
-else
表达式的部分原因他之前拒绝过很多次。但很多人不同意,Guido 是一个 仁慈 的 DFL。此外,使or
以您在其他任何地方所期望的方式工作,同时拒绝在这里做您想做的事(但 Guido 不希望您做),实际上会非常复杂。因此,在这里,Python 可能永远与 C、Perl 和 Lisp 站在同一边,而不是与 Java、Smalltalk 和 Haskell 站在同一边。