Python中对象身份判断异常:bool函数返回不同结果及0>0与False的身份一致性疑问
为什么
0>0 is False和mylist[0] is mylist[1]的bool结果不同? 先直接给结论:0>0对应的对象确实就是False,而且Python里所有的False都是同一个单例对象。你看到的两种不同结果,完全是因为Python对表达式的解析规则在搞鬼!
第一个坑:链式比较的优先级规则
你执行的bool(0>0 is False)之所以返回False,是因为Python对这个表达式的解析和你想的不一样!
在Python中,比较运算符(比如>、<、==)和身份运算符is的优先级是相同的,而且会按照链式比较的逻辑来处理。也就是说,形如a op1 b op2 c的表达式,会被自动解析成:
(a op1 b) and (b op2 c)
而不是你可能以为的(a op1 b) op2 c。
所以0>0 is False实际上被Python翻译成了:
(0 > 0) and (0 is False)
我们一步步算:
0>0的结果是False0 is False的结果是False(0是整数对象,False是布尔对象,两者不是同一个实例)- 最后
False and False的结果还是False,所以bool()包裹后自然返回False
如果想直接判断0>0的结果是不是False,得给0>0加上括号,强制先计算这个部分:
bool( (0>0) is False ) # 这时候结果就是True了
第二个场景:直接比较两个False实例
当你创建列表mylist = [0>0, False]时,0>0的计算结果就是False,所以mylist[0]和mylist[1]指向的是同一个False单例对象(Python会缓存布尔值,所有的False都是同一个实例)。这时候mylist[0] is mylist[1]当然会返回True,用bool()包裹后就是True。
你可以自己验证这个单例特性:
a = False b = 0>0 c = bool("") print(a is b is c) # 输出True,说明三个变量都指向同一个False对象
总结一下
0>0的结果确实是False,且和直接写的False是同一个对象;- 第一个表达式的问题出在链式比较的解析规则上,不是直接比较
0>0的结果和False,而是拆成了两个独立比较的逻辑与; - 第二个场景是直接比较两个
False实例,因为布尔值是单例,所以is返回True。
内容的提问来源于stack exchange,提问作者Steven_Wang
相关产品推荐
相关产品推荐

