为什么表达式 0 < 0 == 0 在 Python 中返回 False?

144 投票
9 回答
9748 浏览
提问于 2025-04-16 18:02

在查看Python 2.6中的Queue.py时,我发现了一个我觉得有点奇怪的结构:

def full(self):
    """Return True if the queue is full, False otherwise
    (not reliable!)."""
    self.mutex.acquire()
    n = 0 < self.maxsize == self._qsize()
    self.mutex.release()
    return n

如果maxsize是0,那么这个队列就永远不会满。

我想问的是,这种情况下是怎么工作的?为什么0 < 0 == 0会被认为是假的呢?

>>> 0 < 0 == 0
False
>>> (0) < (0 == 0)
True
>>> (0 < 0) == 0
True
>>> 0 < (0 == 0)
True

9 个回答

18

你遇到的这个奇怪情况是因为Python可以把多个条件连接在一起。因为它发现0并不小于0,所以它认为整个表达式的结果是假的。一旦你把这个表达式拆开成单独的条件,你就改变了它的功能。最开始,它实际上是在测试 a < b && b == c,这是你原来写的 a < b == c 的意思。

再举个例子:

>>> 1 < 5 < 3
False

>>> (1 < 5) < 3
True
43

因为

(0 < 0) and (0 == 0)

False。你可以把比较运算符连在一起,它们会自动变成一对一的比较。


编辑 -- 关于Python中的True和False的说明

在Python中,TrueFalse其实是bool类型的实例,而boolint的一个子类。换句话说,True实际上就是1。

这意味着你可以像使用整数一样使用布尔比较的结果。这就会导致一些让人困惑的情况,比如

>>> (1==1)+(1==1)
2
>>> (2<1)<1
True

但这些情况只有在你加上括号让比较先计算时才会发生。否则,Python会自动展开比较运算符。

119

在Python中,对于一系列的比较运算符有特别的处理方式,这样可以让范围比较变得更简单。比如说,写 0 < x <= 5 这种方式比写 (0 < x) and (x <= 5) 要好得多。

这种写法叫做 链式比较

在你提到的其他情况中,括号会强制先执行一个比较运算符,然后再执行另一个,所以它们就不再是链式比较了。而且因为 TrueFalse 在计算时可以当作整数使用,所以你从带括号的写法中得到的结果也是这样。

撰写回答