我正在学习 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 类型,这些操作是明确实现的。例如int
egers implement __eq__
但是CHECK_BINOP
如果另一个不是 int
eger,请确保它返回 NotImplemented
。
Ellipsis
对象 doesn't implement __eq__
完全没有。
因此,当您比较整数和省略号时,Python 将始终回退到对象标识,因此它将始终返回 False
。
另一方面,bool
eans 是 int
egers 的子类,因此它们实际上与 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 在某些情况下顺序会改变:
- 如果第二个操作数是第一个操作数的子类,则前两个步骤相反。
- 对于某些隐式相等性检查,在调用任何
__eq__
方法之前检查对象标识。例如,当检查某个项目是否在列表中时,即1 in [1,2,3]
。
关于python - 为什么 ... == True 在 Python 3 中返回 False?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43918816/