在python中如果你写了类似
的东西foo==bar and spam or eggs
如果布尔语句为true,那么python似乎返回垃圾邮件,否则返回egg。有人可以解释这种行为吗?为什么表达式没有被评估为像一个长布尔值?
编辑:具体来说,我正在试图弄清楚为什么'垃圾邮件'或'鸡蛋'因表达而被退回的机制。
答案 0 :(得分:18)
运算符and
和or
是短路的,这意味着如果表达式的结果可以仅通过评估第一个操作数来推断,则不会计算第二个操作数。例如,如果表达式a or b
和a
的计算结果为true,那么b
是什么并不重要,表达式的结果为真,因此b
不是评估。它们的实际工作如下:
a and b
:如果a为假,则不评估b并返回a,否则返回b。a or b
:如果a是真实的,则不评估b并返回a,否则返回b。Falsey和truthy引用在布尔上下文中求值为false或true的值。
然而,在没有更好的选择的日子里,这个和/或成语很有用,但现在有更好的方法:
spam if foo==bar else eggs
和/或习语的问题(除了让初学者感到困惑)是,如果条件为真,它会给出错误的结果,但垃圾邮件评估为假值(例如空字符串)。出于这个原因,你应该避免它。
答案 1 :(得分:5)
这是Python布尔运算符的工作方式。
来自the documentation(最后一段解释了为什么操作员按照他们的方式工作是个好主意):
在布尔运算的上下文中, 以及何时使用表达式 控制流程语句,如下 值被解释为false:
False
,None
,数字为零 类型,空字符串和 容器(包括字符串,元组, 列表,词典,集和 frozensets)。所有其他值都是 解释为真。 (见__nonzero__()
一种更改此方法的特殊方法。)如果运营商
not
产生True
参数为false,否则为False
。表达式
x and y
首先进行评估x
;如果x
为false,则其值为 回;否则,评估y
并返回结果值。表达式
x or y
首先进行评估x
;如果x
为真,则其值为 回;否则,评估y 并返回结果值。(请注意,
and
和or
都不受限制 他们返回的价值和类型False
和True
,而是返回 最后评估的论点。这是 有时候很有用,例如,如果s
是a 应该由a替换的字符串 默认值,如果它是空的, 表达式s or 'foo'
产生了 期望值。因为not
必须这样做 无论如何发明一个价值,它没有 懒得返回相同的值 键入作为参数,例如,not 'foo'
产生False
,而不是''
。)
答案 2 :(得分:3)
原因是Python使用所涉及变量的实际值来评估布尔表达式,而不是将它们限制为True
和False
值。以下值被视为错误:
None
False
''
,()
,[]
,{}
)__nonzero__()
或__len__()
方法返回0或False
有关详细信息,请参阅Python文档的Truth Value Testing部分。特别是:
具有布尔结果的操作和内置函数始终返回
0
或False
表示false,1
或True
表示true,除非另有说明。 (重要的例外:布尔运算or
和and
总是返回其中一个操作数。)
答案 3 :(得分:2)
尝试使用括号使表达式不明确。就是这样,你得到了:
(foo == bar and spam) or eggs