蟒蛇“或"操作员奇怪的行为
问题描述
一、代码:
>>> False or 'hello'
'hello'
这种令人惊讶的行为让您可以检查 x != None 并在一行中检查 x 值:
This surprising behavior lets you check if x != None and check x value in one line:
>>> x = 10 if randint(0,2)==1 else None
>>> (x or 0) > 0
depend on x value...
解释:或"函数如下:(link)"如果 x 为假,则为 y,否则为 x"
Explanation: "or" functions like this: (link) "if x is false, then y, else x"
没有我知道的语言可以让你这样做.那么,为什么要 Python 呢?
No language that i know lets you do this. So, why does Python?
解决方案
听起来您将两个问题合二为一.
It sounds like you're combining two issues into one.
首先,存在短路问题.Marcin 的回答完美地解决了这个问题,所以我不会尝试做得更好.
First, there's the issue of short-circuiting. Marcin's answer addresses this issue perfectly, so I won't try to do any better.
其次,有 or
和 and
返回最后评估的值,而不是将其转换为布尔值.两种方式都有争论,您可以在分歧的任何一方找到许多语言.
Second, there's or
and and
returning the last-evaluated value, rather than converting it to bool. There are arguments to be made both ways, and you can find many languages on either side of the divide.
返回最后评估的值允许 functionCall(x) 或 defaultValue
快捷方式,避免可能浪费的转换(为什么要转换 int
2
放入 bool
1
如果你要做的唯一事情是检查它是否非零?),并且通常更容易解释.因此,由于这些原因的各种组合,C、Lisp、Javascript、Lua、Perl、Ruby 和 VB 等语言都以这种方式做事,Python 也是如此.
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
if the only thing you're going to do with it is check whether it's non-zero?), and is generally easier to explain. So, for various combinations of these reasons, languages like C, Lisp, Javascript, Lua, Perl, Ruby, and VB all do things this way, and so does Python.
始终从运算符返回布尔值有助于捕获一些错误(特别是在逻辑运算符和位运算符容易混淆的语言中),它允许您设计一种语言,其中布尔检查是严格类型检查对于 true
而不是只检查非零,它使运算符的类型更容易写出,并且避免了在两个操作数是不同类型的情况下处理转换(参见 ?:
C 系列语言中的运算符).因此,由于这些原因的各种组合,C++、Fortran、Smalltalk 和 Haskell 等语言都采用这种方式.
Always returning a boolean value from an operator helps to catch some errors (especially in languages where the logical operators and the bitwise operators are easy to confuse), and it allows you to design a language where boolean checks are strictly-typed checks for true
instead of just checks for nonzero, it makes the type of the operator easier to write out, and it avoids having to deal with conversion for cases where the two operands are different types (see the ?:
operator in C-family languages). So, for various combinations of these reasons, languages like C++, Fortran, Smalltalk, and Haskell all do things this way.
在您的问题中(如果我理解正确的话),您使用此功能能够编写如下内容:
In your question (if I understand it correctly), you're using this feature to be able to write something like:
if (x or 0) < 1:
当 x
很容易成为 None
时.这个特定的用例不是很有用,因为更明确的 x if x else 0
(在 Python 2.5 及更高版本中)同样易于编写并且可能更易于理解(至少 Guido这么认为),还因为 None <1
与 0
相同.1
无论如何(至少在 Python 2.x 中,所以你总是至少有两个选项中的一个)……但也有类似的例子,它很有用.比较这两个:
When x
could easily be None
. This particular use case isn't very useful, both because the more-explicit x if x else 0
(in Python 2.5 and later) is just as easy to write and probably easier to understand (at least Guido thinks so), but also because None < 1
is the same as 0 < 1
anyway (at least in Python 2.x, so you've always got at least one of the two options)… But there are similar examples where it is useful. Compare these two:
return launchMissiles() or -1
return launchMissiles() if launchMissiles() else -1
第二个将浪费大量导弹在南极洲炸毁你的敌人两次而不是一次.
The second one will waste a lot of missiles blowing up your enemies in Antarctica twice instead of once.
如果你好奇 Python 为什么会这样:
If you're curious why Python does it this way:
在 1.x 时代, 没有 bool
类型.您有虚假值,例如 None
、0
、[]
、()
、""
等,其他一切都是真的,那么谁需要明确的 False
和 True
?从 or
返回 1
会很愚蠢,因为 1
并不比 [1, 2, 3]
或 dsfsdf"
.到添加 bool
时(逐渐超过两个 2.x 版本,IIRC),当前的逻辑已经牢固地嵌入到语言中,并且更改会破坏很多代码.
Back in the 1.x days, there was no bool
type. You've got falsy values like None
, 0
, []
, ()
, ""
, etc., and everything else is true, so who needs explicit False
and True
? Returning 1
from or
would have been silly, because 1
is no more true than [1, 2, 3]
or "dsfsdf"
. By the time bool
was added (gradually over two 2.x versions, IIRC), the current logic was already solidly embedded in the language, and changing would have broken a lot of code.
那么,他们为什么不在 3.0 中改变它呢?许多 Python 用户,包括 BDFL Guido,会建议您在这种情况下不应该使用 or
(至少因为它违反了TOOWTDI");您应该将表达式的结果存储在变量中,例如:
So, why didn't they change it in 3.0? Many Python users, including BDFL Guido, would suggest that you shouldn't use or
in this case (at the very least because it's a violation of "TOOWTDI"); you should instead store the result of the expression in a variable, e.g.:
missiles = launchMissiles()
return missiles if missiles else -1
事实上,Guido 已经表示他想禁止 launchMissiles() 或 -1
,这也是他最终接受三元 if
的部分原因-else
表达式,他之前拒绝了很多次.但许多其他人不同意,Guido 是一个仁慈的 DFL.此外,让 or
以您在其他地方所期望的方式工作,同时在这里拒绝做您想做的事情(但 Guido 不希望您做),实际上会非常复杂.
And in fact, Guido has stated that he'd like to ban launchMissiles() or -1
, and that's part of the reason he eventually accepted the ternary if
-else
expression that he'd rejected many times before. But many others disagree, and Guido is a benevolent DFL. Also, making or
work the way you'd expect everywhere else, while refusing to do what you want (but Guido doesn't want you to want) here, would actually be pretty complicated.
因此,在这里,Python 可能总是与 C、Perl 和 Lisp 站在同一边,而不是与 Java、Smalltalk 和 Haskell 站在同一边.
So, Python will probably always be on the same side as C, Perl, and Lisp here, instead of the same side as Java, Smalltalk, and Haskell.
相关文章