这如何评估为False
?
1==0 <= 1/0
首先请注意,在Python中:
bols = [False, True]
for A in bols:
for B in bols:
print(f'{str(A):>5}, {str(B):>5}, {str(A<=B):>5}')
输出:
False, False, True
False, True, True
True, False, False
True, True, True
如果您熟悉布尔逻辑,这对您来说自然而然。
现在变得很奇怪:
print(1==1 <= 1/1, 1==0 <= 1/1)
退出:True, False
现在变得奇怪了:
print(1==0 <= 1/0)
退出:False
为什么最后一个没有抛出异常?
我的第一个猜测是因为解析问题。 例如,之前的比较,我们可以修复添加括号的情况:
print(1==1 <= 1/1, (1==0) <= 1/1)
退出:True, True
但是,如果这个问题是解析问题,那么当我们除以0时,为什么python不会引发异常?
如果在最后一个比较中添加括号,则可以强制Python提高ZeroDivision Exeption:
print((1==0) <= 1/0)
退出:ZeroDivisionError: division by zero
此外,为什么以下引发异常?
1==1 <= 1/0
退出:ZeroDivisionError: division by zero
NB:这也适用于其他例外,可能适用于任何例外,因为python不会评估不等式的右侧。
为什么?
我会理解懒惰的评估是否为True
,但是为什么要False
呢?感觉就像是Python中的错误。
答案 0 :(得分:7)
1/0
不会被评估。该表达式触发Python中的链式比较。评估为:
(1 == 0) and (0 <= 1/0)
当达到and
值时,逻辑False
会短路,因此永远不会测试第二个条件。由于1 == 0
的值为False
,因此结果为False
。
在同一方面,其评估为:
(1 == 1) and (1 <= 1/0)
由于第一个表达式为True
,因此将计算第二个表达式。这将导致ZeroDivisionError
。
与比较运算符相比,括号具有更高的优先级。因此,这里不会触发链接比较。该表达式的求值为False <= 1/0
。当然,比较将以ZeroDivisionError
失败。
在这里,您正在定义tuple
个结果。由于两个表达式之间存在逗号分隔,因此元组是隐式的。自1==1 <= 1/1
起,第一个True
的值为True <= 1
。第二个1==0 <= 1/1
自True
起算为False <= 1
。
由于bool
是int
的子类,因此这些比较起作用,因此True
等效于1
,而False
等效于0