【问题标题】:Is False == 0 and True == 1 an implementation detail or is it guaranteed by the language?False == 0 和 True == 1 是实现细节还是由语言保证?
【发布时间】:2011-02-15 09:08:15
【问题描述】:

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

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

任何对官方文档的参考将不胜感激!

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

【问题讨论】:

  • @S.Lott:提出上述问题的原因有很多。因此,在某些情况下,依赖布尔值是整数会使您的代码更简单:您必须更改它吗?或者,您可能会在其他人编写的代码中发现依赖布尔值是整数的地方:您是否会中断您在代码中修改的内容以“修复”现有代码,或者您可以放心当前的编码是正确的?还有很多其他的例子。通俗点来说,就是了解游戏规则,才能玩的好,编程的好。
  • @S.Lott:原帖正好呼应了您的观点:问题本质上是“这是一个实现细节吗?”,因为我完全同意您的观点,即不应依赖于实现细节。如果布尔值是已知值的正式整数,那么问题中的代码不依赖于实现细节,这很好。
  • @S.很多:知道 False==0 和 True==1 可以更容易地计算一个序列中有多少个布尔值是真的:你可以写sum(bool_list)。否则,你必须写sum(1 for x bool_list if x)
  • @dan:这是计算布尔值的一种方法。我想说bool_list.count(True) 更明确;它也快了大约 3 倍……:)
  • @akonsu 正如答案所示,Python 布尔值 实际上是整数(一个特定的子类)。此外,Python 显然 具有 类型;也许您的意思是它“不是静态类型的”?另外,我不确定“我不会在代码中出错”是什么意思。现在,我从不喜欢将布尔值与整数混合,因为它们在概念上是不同的,如果 Python 布尔值不是整数,我不介意,但知道它们的值为 0 和 1 是有用的。

标签: python boolean equality language-specifications


【解决方案1】:

在 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 都是如此。docs for python 2docs for Python 3 都说:

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

在布尔小节中:

布尔值:这些代表真值 False 和 True [...] 布尔值在几乎所有上下文中的行为分别类似于值 0 和 1,但在转换为字符串时,字符串“False”除外或 "True" 分别返回。

还有,for Python 2:

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

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

所以在 Python 4 出现之前你是安全的。 ;-)

【讨论】:

  • 0 == 0.0 返回 True 而 ['zero', 'one'][0.0] 失败。 ['zero', 'one'][False] 有效,因为 bool 是 int 的子类。 (int.__subclasses__() 返回 [])
  • Nitpick:任何提供__index__方法的对象都可以用作列表索引;不仅仅是intlong 的子类。
  • 啊,是的,它也在那里。但最好不要链接到 Python 3.0 文档:3.0 已死。 :)
  • 回复:“在 Python 2.x 中,这不能保证,因为 True 和 False 可能会被重新分配”。恕我直言,虽然这是真的,但任何重新分配 True 或 False 的人都应该得到任何奇怪的后果。具体来说,在重新分配之前存储 True,然后在重新分配之后将结果与 True 进行比较会中断。 a = True; True = 'i am an idiot'; a == True => 错误。除了这样的重新分配,默认值被标准化为 0 和 1,我相信依赖它是常见的做法;例如索引到一个二元素数组,其中 [0] 为假,[1] 为真。
  • 我刚刚注意到另一个官方确认,True 实际上可以被视为 1 和 False 0:docs.python.org/2/library/stdtypes.html#boolean-values。我将此添加到此答案中。
【解决方案2】:

讨论 Python 2.3 中新 bool 类型的 PEP 链接:http://www.python.org/dev/peps/pep-0285/

将bool 转换为int 时,整数值始终为0 或1,但将int 转换为bool 时,布尔值对于除0 以外的所有整数都是True。

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

【讨论】:

    【解决方案3】:

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

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

    所以它可以改变。在 Python 3.x 中,True、False 和 None 是reserved words,所以上面的代码不起作用。

    通常,对于布尔值,您应该假设 False 始终具有整数值 0(只要您不更改它,如上所述),True 可以具有任何其他值。我不一定会依赖 True==1 的任何保证,但在 Python 3.x 上,无论如何都会如此。

    【讨论】:

    • Re " True 可以有任何其他值。我不一定要依赖 True==1" 的任何保证。实际上,您可以依赖 True==1,根据 python.org/dev/peps/pep-0285 和规范 docs.python.org/2/reference/… “布尔值在几乎所有上下文中的行为分别类似于值 0 和 1……”我并不是说它是在 Py 2 中通过重新分配 True 或 False 来覆盖它是不可能的,但我想说的是,除非您项目中的某些程序员是白痴并且进行了这样的重新分配,否则行为是有保证的。
    • 顺便说一句,切换 python 样式有时会出现问题。示例:``` if not (2 != 2): # rextester.com/VSTV98648
    • 当它说0==FalseFalse 时,这真的意味着它是5 吗?
    • 这会将 name False 与绑定到内置范围内的名称的 bool 类型的值混淆。布尔值始终等于 0,无论可能为名称分配什么值。
    猜你喜欢
    • 1970-01-01
    • 2012-08-27
    • 2010-12-30
    • 2023-03-02
    • 2012-01-05
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多