python - 为什么 ... == True 在 Python 3 中返回 False?

标签 python python-3.x if-statement truthiness

我正在学习 python,但我对以下结果感到有点困惑。

In [41]: 1 == True
Out[41]: True

In [42]: if(1):
    ...:     print('111')
    ...:     
111

In [43]: ... == True
Out[43]: False <===== why this is False while '1 == True' is True in previous sample

In [44]: if (...): <==== here ... just behaves like True
    ...:     print('...')
    ...:     
...

根据 the documentation , ... 的真值为 True。

但是我还是觉得上面的代码有点不一致。

...还有一些更有趣的事情:

In [48]: 2==True
Out[48]: False <===== why 1==True returns True while 2==True returns False?

In [49]: if(2):
    ...:     print('222')
    ...:     
222

最佳答案

您混合了两个概念:相等性测试和真值测试。它们在 Python 中并不相同。

我认为触发这个问题的是当你做 if something 时 Python do 隐式转换(它将 something 转换为 bool)但当您执行 something1 == something2 时,它不会进行隐式转换。

Python 数据模型实际上解释了这些操作是如何完成的:

Truth-value testing

  • 首先检查对象是否实现了 __bool__ 方法,如果实现了则使用返回的 bool 值。
  • 如果它没有定义 __bool__ 方法,它会查看 __len__ 方法。如果它被实现,它将使用 len(obj) != 0 的结果。
  • 如果它没有任何一个对象被认为是 True

对于整数 __bool__ method返回 True,除非整数值为 0(然后为 False)。

另一方面,省略号对象 ( ... is the Ellipsis object ) doesn't implement __bool__ or __len__所以它总是 True

Equality testing

相等性测试依赖于两个 参数的__eq__ 方法。它更像是一个操作链:

  • 当第二个操作数作为参数传递时,它检查第一个操作数是否实现了 __eq__
  • 如果没有,那么当第一个操作数作为参数传递时,它会检查第二个操作数是否实现了 __eq__
  • 如果不是,则 Python 检查对象身份(如果它们是同一对象——类似于类 C 语言中的指针比较)

这些操作的顺序可能会有所不同。1

对于内置的 Python 类型,这些操作是明确实现的。例如integers implement __eq__但是CHECK_BINOP如果另一个不是 integer,请确保它返回 NotImplemented

Ellipsis 对象 doesn't implement __eq__完全没有。

因此,当您比较整数和省略号时,Python 将始终回退到对象标识,因此它将始终返回 False

另一方面,booleans 是 integers 的子类,因此它们实际上与 int 进行比较(它们是另一个 int 毕竟)。 bool 值实现为 1 (True) 和 0 (False)。所以他们比较相等:

>>> 1 == True
True
>>> 0 == False
True

>>> 1 == False
False
>>> 0 == True
False

尽管源代码可能很难理解,但我希望我能充分解释这些概念(源代码是针对 CPython 实现的,其他 Python 实现(如 PyPy、IronPython 中的实现可能有所不同!)。重要的外卖信息应该是 Python 不在相等性检查中进行隐式转换,相等性测试与真值测试根本无关。内置类型的实现几乎总能给出有意义的结果:

  • 所有数字类型都以某种方式实现相等性( float 与整数比较,复数与整数和 float 比较)
  • 所有非零和非空的都是真实的

但是,如果您创建自己的类,您可以根据需要覆盖相等性和真值测试(然后您可能会造成很多困惑)!


1 在某些情况下顺序会改变:

  1. 如果第二个操作数是第一个操作数的子类,则前两个步骤相反。
  2. 对于某些隐式相等性检查,在调用任何__eq__ 方法之前检查对象标识。例如,当检查某个项目是否在列表中时,即 1 in [1,2,3]

关于python - 为什么 ... == True 在 Python 3 中返回 False?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43918816/

相关文章:

python - 使用多列条件过滤,Python 3.6

Python:&= 运算符

python - Python 中的简单合并排序错误

javascript - JS点击事件取决于div宽度

python - 用python 3.x中最简单的代码向字典添加列表

python - 如何配置 Apache Airflow 以使用 MS SQL Server Windows 身份验证

python - 属性错误 : module 'tensorflow' has no attribute 'get_default_graph'

python - 如何根据参数指定调用哪个__init__?

c - 如何理解if语句中的这种条件?

python - 如何按 pandas 中的列进行分组并根据列值应用 ifelse