为什么…==Python 3中的True返回False?
我正在学习python,但是下面的结果让我有点困惑为什么…==Python 3中的True返回False?,python,python-3.x,if-statement,truthiness,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 (...):
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('...')
...:
...
在python中,大多数(所有?)对象都有bool
值。“真值为真”的含义意味着bool(obj)
的计算结果为真
另一方面,在许多情况下,True
被视为1
(而False
被视为0
),在执行以下操作时可以看到:
sum([True, True, False])
# (1 + 1 + 0) -> 2
这就是为什么会得到1==True
-->True
文档中有一个更明确的定义:
布尔值是两个常量对象False和True。它们用于表示真值(尽管其他值也可以被视为假或真)在数值上下文中(例如,当用作算术运算符的参数时),它们的行为分别类似于整数0和1
从文档中的自身:
这些代表了真值False和True。表示值False和True的两个对象是唯一的布尔对象。布尔类型是整数类型的一个子类型,布尔值在几乎所有上下文中的行为分别与值0和1类似,例外情况是当转换为字符串时,分别返回字符串“False”或“True”
任何物体都可以进行以下测试:
任何对象都可以测试真值,用于if或while条件,或作为下面布尔运算的操作数。以下值被认为是错误的:
- 没有
- 假的
- 任何数字类型的零,例如0、0.0、0j
- 任何空序列,例如,,(),[]
- 任何空映射,例如,{}
- 用户定义类的实例,如果该类定义了bool()或len()方法,则该方法返回整数零或bool值False。[1]
如果…
将进入分支。省略号
对象被视为true
。然而,这并不意味着它必须等于True
。只有bool(…)==True
if
将根据条件隐式调用bool
,因此:
if ...:
# something
将被评估为您编写了:
if bool(...):
# something
以及:
然而,这里有一个陷阱
True
等于1
和False
等于0
,但那只是因为python中的bool
子类int
eger。我相信这是1==True
这很奇怪,不是…=正确
1
等于True
,因为在Python中布尔是整数的子类(因为)。看看你自己:
>>> issubclass(bool, int)
True
你混合了两个概念:平等性测试和真值测试。它们在Python中是不同的 我认为引发这个问题的原因是Python在你做
某件事的时候做了一个隐式转换(它把某件事转换成bool
),但是当你做something1==something2
的时候它不做隐式转换
Pythons数据模型实际上解释了这些操作是如何完成的:
- 它首先检查对象是否实现了
\uu bool\uu
方法,如果实现了,则使用返回的布尔值李>
- 如果它没有定义
\uuuu bool\uuuu
方法,它将查看\uuu len\uuu
方法。如果它被实现,它将使用len(obj)!=0
李>
- 如果没有任何一个,则该对象被视为
True
对于整数,返回True
,除非整数值为0
(然后为False
)
另一方面,省略号对象()总是True
相等性测试依赖于两个参数的\uuuuuu eq\uuu
方法。这更像是一个操作链:
- 当第二个操作数作为参数传递时,它检查第一个操作数是否实现了
\uuuuuu eq\uuuu
- 如果没有,则当第一个操作数作为参数传递时,它会检查第二个操作数是否实现了
\uuuuu eq\uuuu
- 如果没有,Python将检查对象标识(如果它们是相同的对象-类似于类C语言中的指针比较)
这些操作的顺序可能会有所不同。1
对于内置Python类型,这些操作是显式实现的。例如,但如果另一个不是int
eger,则确保返回NotImplemented
省略号根本就是对象
因此,当您比较整数和省略号时,Python将始终回退到对象标识,因此它将始终返回False
另一方面,bool
eans是int
egers的一个子类,因此它们实际上与int
进行比较(毕竟它们是另一个int
)。布尔值实现为1
(True
)和0
(False
)。因此,他们比较平等:
>>> 1 == True
True
>>> 0 == False
True
>>> 1 == False
False
>>> 0 == True
False
尽管源代码可能很难理解,但我希望我已经充分解释了这些概念(源代码是针对CPython实现的,其他pypypy、IronPython等Python实现中的实现可能有所不同!)。重要的附加信息应该是Python在平等性检查中不进行隐式转换,平等性测试与tr无关
>>> issubclass(bool, int)
True
>>> 1 == True
True
>>> 0 == False
True
>>> 1 == False
False
>>> 0 == True
False