False == 0 和 True == 1 是实现细节还是语言保证的?

300 投票
4 回答
335896 浏览
提问于 2025-04-15 22:19

在Python中,False == 0True == 1是否一定成立呢?假设用户没有重新赋值。这意味着,不管Python的版本如何(包括现在的和将来的版本),下面这段代码是否总是能得到相同的结果呢?

0 == False  # True
1 == True   # True
['zero', 'one'][False]  # is 'zero'

如果能引用官方文档,那就太好了!

正如许多回答中提到的,bool是从int继承来的。因此,这个问题可以重新表述为:“官方文档是否明确说明程序员可以依赖布尔值是整数,并且它们的值是01?”这个问题对于编写稳健的代码非常重要,这样代码就不会因为实现细节而出错!

4 个回答

23

在Python 2.x中,这一点并不一定可靠:

>>> False = 5
>>> 0 == False
False

所以这个情况可能会改变。在Python 3.x中,True、False和None是一些特别的保留字,这意味着上面的代码是不能正常工作的。

一般来说,关于布尔值(也就是True和False),你可以认为False的整数值总是0(只要你不去改变它),而True则可能有其他任何值。我不会太依赖于True==1这个说法,但在Python 3.x中,这个关系总是成立,不管怎样。

87

这里有一份PEP(Python增强提案),讨论了Python 2.3中新加入的布尔类型:http://www.python.org/dev/peps/pep-0285/

当把布尔值转换成整数时,结果总是0或1;而把整数转换成布尔值时,除了0以外,所有的整数都会变成True。

>>> int(False)
0
>>> int(True)
1
>>> bool(5)
True
>>> bool(-5)
True
>>> bool(0)
False
238

在Python 2.x中,这并不是一定的,因为TrueFalse是可以被重新赋值的。不过,即使发生了这种情况,布尔值的True和False在比较时仍然会正确返回。

在Python 3.x中,TrueFalse是关键字,它们始终等于10

在Python 2中,通常情况下,以及在Python 3中,总是:

False对象的类型是bool,它是int的一个子类:

    object
       |
     int
       |
     bool

这就是为什么在你的例子中,['zero', 'one'][False]可以正常工作的唯一原因。如果用一个不是整数子类的对象,这个方法就不行了,因为列表索引只适用于整数,或者那些定义了__index__方法的对象(感谢mark-dickinson)。

编辑:

这对于当前的Python版本和Python 3都是正确的。Python 2的文档Python 3的文档都说:

有两种类型的整数:[...] 整数(int)[...] 布尔值(bool)

在布尔值的子部分中:

布尔值:这些表示真值False和True [...] 布尔值在几乎所有情况下都像整数0和1一样,唯一的例外是当转换为字符串时,分别返回字符串"False"或"True"。

对于Python 2,还有相关内容

在数字上下文中(例如作为算术运算符的参数时),它们[False和True]分别表现得像整数0和1。

所以在Python 2和3中,布尔值被明确视为整数。

所以在Python 4到来之前,你是安全的。;-)

撰写回答