2014-12-03 38 views
23

标准约定使用if foo is None而不是if foo == None来测试值是否具体为None布尔标识== True对比为真

如果你想确定一个值是否正好是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 booleans - if x:, vs if x == True, vs if x is True。但是,它只能确定是否应使用if fooif foo == Trueif foo is True来确定foo是否具有真实值。


更新:据PEP 285§规格:

值假和真将是单身,像无。

+2

@AshwiniChaudhary:[那根本不是真的](https://docs.python.org/2/library/constants.html)。真和假都是单身。 – Kevin 2014-12-03 16:37:15

+1

@AshwiniChaudhary'True'和'False'是单身人士。 'bool'构造函数将通过标识返回'True'或'False',所以你不能创建一个布尔值,它不会使用'is'与'True'或'False'进行比较。 – 2014-12-03 16:40:02

+0

@AshwiniChaudhary另请参阅:https://hg.python.org/cpython/rev/01a7e66525c2/ – 2014-12-03 16:41:42

回答

16

如果你想确定一个值是否完全是真的(不只是一个真实的值),是否有任何理由使用if foo == True而不是如果foo为True?

如果你想确保foo真的是一个布尔值True,并使用is操作。

否则,如果foo类型实现自己__eq__()比较True时返回真值十岁上下,你可能最终得到一个意想不到的结果。

作为一个经验法则,您应该始终使用is与内置常量True,FalseNone

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

在理论上,is将比==更快,因为后者必须履行类型定制__eq__实施方式中,而is可以直接比较对象标识(例如,存储器地址)。

我不知道各种Python实现的源代码,但我认为他们中的大多数可以通过使用一些内部标志来存在魔术方法来优化,所以我怀疑你不会注意练习中的速度差异。

+0

对于非常广泛的库(如numpy),它们有自己的布尔值版本,这是错误的。 – pindakaas 2017-12-18 16:20:59

+0

@pindakaas:不,这不是“错误的”。这里是对“如果你想确定一个值是否完全是真的(不只是一个真实的值)”这个问题的回答。一些像numpy这样的图书馆有自己的“真实”类型的论点在这里并不成立! – 2017-12-22 11:16:37

-1

编辑:重新is True VS ==

存在的情况,那就是:

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

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

此外,对于单身的警戒值,你可以只使用一个类

class SentinelTime(object): pass 

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

你不想用if var == True:,你真的想要if var:

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

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

退房这个职位有什么结果为FalseEvaluation of boolean expressions in Python

+1

OP明确声明“如果您想确定某个值是否完全为真(不仅仅是一个真实值)” – 2014-12-03 16:31:20

5

没有任何理由使用检查foo ==真,而不是如果foo是真“

>>> 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:您为什么要在True,1或任何“真值”之间做出区别?

+0

FWIW:所有出现的'if x == True'已被替换为'if x is (C)Python 2.6中的True',请参考https://hg.python.org/cpython/rev/01a7e66525c2/ - 我假设这回答你的问题。请注意,它被认为是纯音测试,没有很好的理由,明确地测试“True”或“False”;) – 2014-12-03 16:45:08

1

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

但是,如果您确实需要确定它确切地是True而没有别的,请使用is。使用==会给你1 == True

0

这是一个测试,可以让你看到真正的3种形式的测试之间的区别:

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 

正如你可以看到有情况他们都带来不同的结果。

10

结合切勿使用is True与numpy的(和衍生物,如大熊猫):

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_ 
+0

相反,如果您想知道该对象是否是Python的实际内置'True'对象,'是True'仍然是需要解决的问题。 NumPy布尔型数组标量并不是内置的“True”对象,无论他们是否假装是这样,并且它们与实际布尔值之间存在关键的实现和行为差异。 – user2357112 2017-04-26 00:05:16

+0

我其实同意你的看法:我个人比较喜欢'真',并且尽可能地使用它。但我很惊讶它不适合numpy/pandas,并认为在这里分享是有用的。 – kadee 2017-05-07 11:18:25