python“;或;操作员奇怪的行为

python“;或;操作员奇怪的行为,python,operators,boolean,Python,Operators,Boolean,首先,守则: >>> False or 'hello' 'hello' 这种令人惊讶的行为使您可以检查x!=无并检查一行中的x值: >>> x = 10 if randint(0,2)==1 else None >>> (x or 0) > 0 depend on x value... 说明:“或”函数如下:() 如果x为假,则为y,否则为x 我所知道的任何语言都不允许你这么做。 那么,为什么Python会这样做呢 实际上很多语言都

首先,守则:

>>> False or 'hello'
'hello'
这种令人惊讶的行为使您可以检查x!=无并检查一行中的x值:

>>> x = 10 if randint(0,2)==1 else None
>>> (x or 0) > 0
depend on x value...
说明:“或”函数如下:() 如果x为假,则为y,否则为x


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

实际上很多语言都有。参见维基百科关于

关于短路评估存在的原因,维基百科写道:

如果用作条件的两个表达式都是简单的布尔变量, 实际上,它可以更快地计算布尔运算中使用的两个条件 一次操作,因为它总是需要一个计算周期, 与短路评估中使用的一个或两个循环相反 (取决于第一个的值)


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


那你不懂很多语言。我想不出一种我所知道的语言不表现出这种“短路”行为

之所以这样做,是因为这样说很有用:

a = b or K
这样,如果b不是None(或falsy),a要么变成b,如果不是,则得到默认值K。

“我所知道的任何语言都不允许您这样做。那么,为什么Python会这样做呢?”您似乎认为所有语言都应该是相同的。难道你不希望编程语言的创新产生人们所珍视的独特特性吗


您刚刚指出了它为什么有用,那么Python为什么不这么做呢?也许你应该问为什么其他语言不这样做。

听起来你好像把两个问题结合在一起了

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

其次,
返回最后一个评估值,而不是将其转换为bool。这两种观点都有争议,你可以在分歧的两边找到许多语言

返回上一个计算值允许使用
函数调用(x)或defaultValue
快捷方式,避免可能的浪费转换(如果要使用
int
2
进行转换,只需检查它是否为非零,那么为什么要将
bool
1
转换为
1
),而且通常更容易解释。因此,由于这些原因的各种组合,像C、Lisp、Javascript、Lua、Perl、Ruby和VB这样的语言都是这样做的,Python也是如此

始终从运算符返回布尔值有助于捕获某些错误(特别是在逻辑运算符和位运算符容易混淆的语言中),并且它允许您设计一种语言,在这种语言中,布尔检查是严格类型的
true
检查,而不仅仅是非零检查,它使运算符的类型更容易写出,并且避免了在两个操作数类型不同的情况下进行转换(请参见C族语言中的
?:
运算符)。所以,由于这些原因的各种组合,像C++、FORTRAN、SMALLATE和HASKELL这样的语言都是这样做的。
在您的问题中(如果我理解正确),您使用此功能可以编写如下内容:

if (x or 0) < 1:
第二种方法将浪费大量导弹,两次而不是一次炸毁你在南极洲的敌人


如果您想知道Python为什么会这样做:

回到1.x天,没有
bool
类型。你有像
None
0
[]
()
”等虚假的值,而其他一切都是真的,所以谁需要显式的
?从
返回
1
是愚蠢的,因为
1
并不比
[1,2,3]
“dsfsdf”
更真实。当添加
bool
时(逐渐超过两个2.x版本,IIRC),当前的逻辑已经牢固地嵌入到语言中,而更改会破坏很多代码

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

missiles = launchMissiles()
return missiles if missiles else -1
事实上,Guido已经声明他想禁止
发射导弹()或-1
,这也是他最终接受三元
if
-
else
表达式的部分原因,他以前多次拒绝过这个表达式。但许多其他人不同意,Guido是一个仁慈的DFL。此外,让
按照您在其他地方所期望的方式工作,同时拒绝在这里做您想要做的事情(但Guido不希望您做),这实际上相当复杂



这样,Python可能总是与C、Perl和Lisp相同,而不是与java、SimalTalk和Haskell等相同的一面。

< P>这个行为并不奇怪,如果Python具有关于<强>或>的以下特征,这是非常简单的。逻辑运算符:

  • 短路求值:它只对需要的操作数求值
  • 非强制结果:结果是其中一个操作数,未强制为
    bool
此外:

  • 对象的真值仅对
    0
    []
    {}
    。其他所有内容的真值均为True(这是一种简化;正确的定义在中)
将这些功能结合起来,它将导致:

  • :如果第一个操作数的计算结果为,则将其短路并返回。或返回第二个操作数。
  • missiles = launchMissiles() return missiles if missiles else -1
>>> a or b or c or d

>>> a and b and c and d
drink = getColdBeer() or pickNiceWine() or random.anySoda or "meh, water :/"
username = cmdlineargs.username or configFile['username'] or DEFAULT_USERNAME