2014-12-03 83 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