False == 0 和 True == 1 是实现细节还是语言保证的?
在Python中,False == 0
和True == 1
是否一定成立呢?假设用户没有重新赋值。这意味着,不管Python的版本如何(包括现在的和将来的版本),下面这段代码是否总是能得到相同的结果呢?
0 == False # True
1 == True # True
['zero', 'one'][False] # is 'zero'
如果能引用官方文档,那就太好了!
正如许多回答中提到的,bool
是从int
继承来的。因此,这个问题可以重新表述为:“官方文档是否明确说明程序员可以依赖布尔值是整数,并且它们的值是0
和1
?”这个问题对于编写稳健的代码非常重要,这样代码就不会因为实现细节而出错!
4 个回答
在Python 2.x中,这一点并不一定可靠:
>>> False = 5
>>> 0 == False
False
所以这个情况可能会改变。在Python 3.x中,True、False和None是一些特别的保留字,这意味着上面的代码是不能正常工作的。
一般来说,关于布尔值(也就是True和False),你可以认为False的整数值总是0(只要你不去改变它),而True则可能有其他任何值。我不会太依赖于True==1
这个说法,但在Python 3.x中,这个关系总是成立,不管怎样。
这里有一份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
在Python 2.x中,这并不是一定的,因为True
和False
是可以被重新赋值的。不过,即使发生了这种情况,布尔值的True和False在比较时仍然会正确返回。
在Python 3.x中,True
和False
是关键字,它们始终等于1
和0
。
在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到来之前,你是安全的。;-)