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


244

是否可以保证False == 0True == 1,在Python中(假设用户没有重新分配它们)?例如,是否以任何方式保证以下代码将始终产生相同的结果,而不管Python的版本如何(既有现有版本,也可能是未来版本)?

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

任何对官方文档的引用将不胜感激!

编辑:如许多答案所述,bool继承自int。因此,可以将问题改写为:“文档是否正式声明程序员可以依赖从整数(带有值01?)继承的布尔 ”。这个问题与编写不会因为实现细节而失败的健壮代码有关!


63
@ S.Lott:提出上述问题的原因很多。因此,在某些情况下,依靠布尔值作为整数会使您的代码更简单:您是否需要更改它?或者,您可能会发现由别人编写的依赖布尔值(即布尔值)的代码中的位置:是为了“修复”现有代码而中断了代码中正在修改的内容,还是可以放心当前代码是正确的?还有很多其他示例。一般来说,最好了解游戏规则,以便您可以很好地玩游戏并以声音方式编程。
埃里克·勒比格

10
@ S.Lott:原始帖子恰好反映了您的观点:问题本质上是“这是实现细节吗?”,因为我完全同意您的观点,即不应依赖实现细节。如果布尔值是已知值的正式整数,那么问题中的代码不依赖于实现细节,这很好。
Eric O Lebigot 2010年

5
@S。很多:知道False == 0和True == 1可以更轻松地计算序列中有多少布尔值是真实的:您可以编写sum(bool_list)。否则,您将不得不编写sum(1 for x bool_list if x)
dan04'7

8
@dan:这是计算布尔值的一种方法。我想说bool_list.count(True)的比较明确。它的速度也快3倍……:)
埃里克·奥·莱比格

2
@akonsu作为答案显示,Python的布尔实际上整数(的具体子类)。此外,Python显然具有类型。也许您是说它不是“静态类型”?另外,我不确定“我不会在代码中出错”的意思。现在,我从不喜欢将布尔值与整数混合,因为它们在概念上是不同的,并且我不介意Python布尔值不是整数,但是知道它们的值是0和1很有用。
Eric O Lebigot

Answers:


183

在Python 2.x的,这是没有保证的,因为它是可能的True,并False重新分配。但是,即使发生这种情况,仍然正确返回布尔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.6文档和python 3文档都说:

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

在布尔小节中:

布尔值:它们表示真值False和True布尔值在几乎所有上下文中的行为分别类似于值0和1,但例外是当转换为字符串时,字符串“ False”或“ True”分别返回。

对于Python 2也有:

在数字上下文中(例如,用作算术运算符的参数时),它们的[False和True]分别类似于整数0和1。

因此,布尔值在Python 2.6和3中被明确视为整数。

因此,在Python 4出现之前,您是安全的。;-)


2
0 == 0.0当['zero','one'] [0.0]失败时返回True。['zero','one'] [False]起作用是因为bool是int的子类。(int .__ subclasses __()返回[<type'bool'>]])
luc 2010年

20
Nitpick:提供__index__方法的任何对象都可以用作列表索引;不只是int或的子类long
马克·迪金森

是的,它也在那里。但是最好不要链接到Python 3.0文档:3.0已死。:)
马克·迪金森

4
回复:“在Python 2.x中,这不能保证,因为可能会重新分配True和False”。恕我直言,尽管这是事实,但重新分配“是”或“错”的任何人都应该得到他们所得到的任何奇怪结果。具体来说,在重新分配之前存储True,然后将结果与重新分配之后的True进行比较可能会失败。a = True; True = 'i am an idiot'; a == True=>错误。除了这种重新分配之外,默认值标准化为0和1,我相信依靠它是一种常见的做法。例如,索引到一个由两个元素组成的数组,其中[0]包含错误的情况,[1]为true。
ToolmakerSteve

我刚刚注意到另一个官方确认的事实,即实际上可以将True视为1和False 0:docs.python.org/2/library/stdtypes.html#boolean-values。我将此添加到此答案。
Eric O Lebigot


22

在Python 2.x中,根本无法保证:

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

因此它可能会改变。在Python 3.x中,True,False和None是保留字,因此上面的代码不起作用。

通常,使用布尔值时,您应该假设False始终具有0的整数值(只要您不进行上述更改即可),True可以具有任何其他值。我不一定要依靠True==1,但是在Python 3.x上,无论如何,情况总是如此。


3
关于“ True可以具有任何其他值。我不一定要依赖True == 1的任何保证”。实际上,根据python.org/dev/peps/pep-0285specdocs.python.org/2/reference/…,您可以依赖True == 1, “布尔值的行为分别类似于值0和1 ,几乎在所有情况下...”我并不是说不可能在Py 2中通过重新分配True或False来覆盖此问题,但我是说除非您项目中的某些程序员是白痴并且做了这样的重新分配,否则行为得到保证。
ToolmakerSteve

-2

很简单。由于布尔与将整数评估为布尔有关,因此只有0给出错误的答案。所有非零值,浮点数,整数(包括负数)或您拥有的所有值都将返回true。

一个为什么有用的很好的例子是确定设备的电源状态。On是任何非零值,off是零。从电子上讲,这是有道理的。

若要相对确定值之间的正确或错误,您必须将其与之进行比较。这适用于字符串和数值,使用==!=<> >=<=等。

您可以为变量分配一个整数,然后根据该变量值获得true或false。


1
问题在于Python是否保证True == 1,而不是整数的布尔值。
Eric O Lebigot

-3

只需编写int(False),您将得到0,如果键入int(True)它将输出1


4
这仅仅意味着在假和True是有效的输入int(),用一个简单的数字的意义,而不是它们完全相同0和1
埃里克öLebigot

-5

假是布尔。它具有不同的类型。它是不同于整数的0的对象。

0 == False因为将False强制转换为整数,所以返回True。int(False)返回0

==运算符的python文档说(help('==')):

运营商<>==>=<=,和!=比较两个对象的值。这些对象不必具有相同的类型。如果两者都是数字,则它们将转换为通用类型。

结果,需要比较时将False转换为整数。但它不同于0。

>>> 0 is False
False

26
这不是很正确: bool是的子类int,因此从实际意义上讲,布尔值整数。例如,isinstance(True, int)返回True。并且相等检查不会将布尔值转换为int,因为不需要转换:它只是int.__cmp__直接调用。请注意,该值bool.__cmp__ is int.__cmp__也计算为True
马克·迪金森

3
-1为这个答案。bool和int之间关系的描述不正确(在Python 2中)。isinstance(True, int)=>是的。也就是说,True 整数,不需要转换。
ToolmakerSteve 2014年

我有一个脚本返回了False或Int ...使用了while response is False工作,while response == False但是没有..谢谢!
curl_brackets16-4-23

5
0 is False是错误的,什么也没告诉你。在交互式解释器,输入x = -10,然后y = -10,然后x is y那会有假的。仅仅因为在某些情况下(某些情况下,Python解释器会重用相同的整数对象(将整数文字存储为常量,对小整数进行插值))存在优化,这并不意味着is在要测试整数值相等时就应该使用该优化。
马丁·彼得斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.