布尔等式 = = 真与真

标准惯例是使用 if foo is None而不是 if foo == None来测试一个值是否是特定的 None

如果您想确定一个值是否正好是 True(而不仅仅是类真值) ,有什么理由使用 if foo == True而不是 if foo is True吗?这在 CPython (2.x 和3.x)、 Jython、 PyPy 等实现之间是否有所不同。?

例如: 假设 True被用作一个单例值,你想要区别于值 'bar',或者任何其他类真值:

if foo is True: # vs foo == True
...
elif foo == 'bar':
...

是否存在使用 if foo is True会产生与 if foo == True不同的结果的情况?

注意: 我知道 Python 布尔值-if x: ,vs if x = = True,vs if x 为 True。然而,它只是处理通常是否应该使用 if fooif foo == Trueif foo is True来确定 foo是否具有类真值。


更新: 根据 PEP 285规范:

False 和 True 值将是单例,就像 Nothing 一样。

92303 次浏览

关于:

是否存在使用 if foo is True会产生与 if foo == True不同的结果的情况?

有个案子,是这样的:

In [24]: 1 is True
Out[24]: False


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

另外,如果你想使用单例作为前哨值,你可以创建一个对象:

sentinel_time = object()


def f(snth):
if snth is sentinel_time:
print 'got em!'
f(sentinel_time)

you don't want to use if var == True:, you really want if var:.

想象你有一个名单。你不在乎一个列表是否是“ True”,你只想知道它是否是空的。所以..。

l = ['snth']
if l:
print l

看看这篇文章的评价是 False: Python 中布尔表达式的计算

是否有理由使用 if foo = = True 而不是 if foo is True?”

>>> d = True
>>> d is True
True
>>> d = 1
>>> d is True
False
>>> d == True
True
>>> d = 2
>>> d == True
False

请注意,boolint的一个子类,而 True具有整数值 1。为了回答您的问题,如果您想检查某个变量是否“完全正确”,您必须使用标识符 is但是实际上不是 pythonic... 我可以问一下你真正的用例是什么吗? —— IOW: 为什么你想在 True1或任何“真实”值之间做出区别?

如果您想确定一个值是否完全为 True (而不仅仅是一个类似 True 的值) ,是否有理由使用 If foo = = True 而不是 If foo is True?

If you want to make sure that foo really is a boolean and of value True, use the is operator.

否则,如果 foo类型实现自己的 __eq__(),该 __eq__()在与 True进行比较时返回 true-ish 值,那么您可能会得到一个意外的结果。

根据经验,应该始终使用带有内置常量 TrueFalseNoneis

这在 CPython (2.x 和3.x)、 Jython、 PyPy 等实现之间是否有所不同?

理论上,is==快,因为后者必须尊重类型的自定义 __eq__实现,而 is可以直接比较对象标识(例如,内存地址)。

我不太熟悉各种 Python 实现的源代码,但是我认为大多数 Python 实现都可以通过使用一些内部标志来优化它们,因此我怀疑您在实践中不会注意到速度上的差异。

大多数时候,你不应该关心这样的细节。要么您已经知道 foo是一个布尔值(因此可以使用 if foo) ,要么您知道 foo是其他值(在这种情况下不需要测试)。如果不知道变量的类型,可能需要重构代码。

但是,如果您确实需要确定它正好是 True而不是其他任何东西,那么使用 is。使用 ==将得到 1 == True

这里有一个测试,可以让你看到 True 的三种测试形式之间的区别:

for test in ([], [1], 0, 1, 2):
print repr(test), 'T' if test else 'F', 'T' if test == True else 'F', 'T' if test is True else 'F'


[] F F F
[1] T F F
0 F F F
1 T T F
2 T F F

正如您所看到的,在某些情况下,所有这些方法都会产生不同的结果。

不要将 is True与麻木(以及大熊猫等衍生物)结合使用:

In[1]: import numpy as np
In[2]: a = np.array([1, 2]).any()
In[4]: a is True
Out[4]: False
In[5]: a == True
Out[5]: True

这让我很意外,因为:

In[3]: a
Out[3]: True

我想解释是这样的:

In[6]: type(a)
Out[6]: numpy.bool_

如果大多数时候不是你想要的,那么使用 foo is True而不是 foo == True(或者仅仅是 foo)。

我曾经看到过使用 foo is True来检查参数 foo是否真的是一个布尔值。

  1. 它与 python 的 Duck 类型哲学(通常不应检查类型)相矛盾。对于采用鸭式输入的程序员来说,使用 True的函数与使用其他真实值的函数不同是违反直觉的
  2. 即使你想检查类型,最好是像下面这样做:
def myFunction(foo):
if not isinstance(foo, bool):
raise ValueError("foo should be a boolean")
>>> myFunction(1)
Exception: ValueError "foo should be a boolean"

有几个原因:

  • Bool 是 is运算符等价于 isinstance(a, bool) and a的唯一类型。原因是 TrueFalse单身。换句话说,这是因为 Python 的一个鲜为人知的特性(特别是当一些教程告诉您 TrueFalse只是 10的别名时)。
  • 如果您使用 isinstance ,而程序员不知道您的函数不接受 truthy-value,或者如果他们正在使用 numpy并忘记将 numpy-boolean 转换为 python-boolean,则 他们会知道自己做错了什么,并且将能够进行调试。

比较一下

def myFunction(foo):
if foo is True:
doSomething()
else:
doSomethingElse()

在这种情况下,myFunction(1)不仅不会引发异常,而且可能与预期的操作相反。例如,如果有人使用了 numpy 布尔值,那么就很难找到 bug。

那么什么时候应该使用 is True呢?

编辑: 这是不好的做法 ,从3.9开始,当您尝试使用 is与文字进行比较时,python 会发出警告。见下面@JayDadhania 的评论。总之,is不应该用来与文字进行比较,只能用来检查内存地址的相等性。

只是不要使用它。如果你需要检查类型,使用 isinstance

旧段落:

基本上,它只用作 isinstance(foo, bool) and foo的简写

我看到的唯一情况是,当您显式地想要检查一个值是否为 true,并且稍后还将检查该值是否为另一个 true 值时。例子包括:

if foo is True:
doSomething()
elif foo is False:
doSomethingElse()
elif foo is 1: #EDIT: raises a warning, use == 1 instead
doYetSomethingElse()
else:
doSomethingElseEntirely()