最近在StackOverflow上看到了一个问题,为什么Python中的None is None is None返回True,看到大家的讨论后对Python中的比较运算有了更深的认识。
None is None is None 不同于 (None is None) is None
题主和很多人一开始都认为None is None is None
就等同于(None is None) is None,
而后者百分之百是False,因为True is None == False.
然而问题的关键是is
在Python中是比较运算符,而不是算数运算符。
括号在比较运算中并不是改变运算优先级,而是直接返回括号内比较运算的结果,这个结果只会是True
或者False
,而True
和False
已经不是原来比较的对象了。
就像(1 < 2) < 3
在Python中虽然是True但事实上比较的是True < 3
, 而True在比较运算中是当作1看待的。换成了(3 > 2) > 1
结果就是False了,因为True是等于1的。
那么Python是如何处理None is None is None
的呢?
Python中连续进行比较运算的底层实现
上一节提到了(3 > 2) > 1
在Python中是False,但是懂一点Python的人都知道3 > 2 > 1
在Python中是合法的并且返回True,我们可以看一下这一个表达式在Python字节码中是如何进行处理的。
我们可以看到3 > 2 > 1
事实上就相当于3 > 2 and 2 > 1
。Python中对于
a compare_operation1 b compare_operation c
的处理就是
a compare_operation1 b and b compare_operation c
所以对于比较运算符的is
,None is None is None
就是None is None and None is None
,结果是True也就没什么问题了。
对于Python的这一条特性大家平时一般都用在连续的方向一致的大小比较中,例如:
a < b < c a <= b < c a > b >= c > d
事实上我们完全可以混用各种比较运算符,例如:
值得注意的是is not
被视为一个比较运算符,所以途中的第三个表达式相当于True is not Flase and False is False
。