2012-04-19 105 views
5

風格指南http://www.python.org/dev/peps/pep-0008爲什麼沒有真正的==真:

的最後一個點讀...

布爾值,不要比較,真或假使用==。

爲什麼?

編輯 只是要清楚什麼IM要求(和它的指示問題本身的),當你寫

if something: 
    print "something is true" 

你正在做一個隱式轉換爲布爾值可能會或可能不會根據工作關於什麼是真正意義。恕我直言,這種形式的編程是不鼓勵的,因爲它可能導致的副作用。

numberOfApples = -1 
if numberOfApples: 
    print "you have apples" # is not what is intended. 

if numberOfApples == True: 
    print "you have apples" # is also not what is intended. 

iHaveApples = numberOfApples > 0 
if iHaveApples is True: # Edit: corrected this.. the "is" is better than the == 
    print "you have apples" # is correct. 

隱式轉換會掩蓋邏輯錯誤。那麼爲什麼風格指南鼓勵這個呢?

+0

我開始認爲布爾測試的最佳樣式被標記爲樣式指南中最差的樣式。 如果numberOfApples爲True: 將清除numberOfApples不是一個布爾值。 – 2012-04-19 19:40:06

+0

那麼你真正想要的是比較如果x是bool()類型,如果它是,如果它是真或假 – 2012-04-22 16:50:47

+0

@PedroWerneck正確。因此,風格指南錯誤地說,測試bool的最糟糕的方式是如果bool_type是[True | False]:因爲它實際上是最好的方式 – 2012-04-23 14:55:33

回答

7

這意味着你應該寫

if greeting: 

相反的:

if greeting == True: 

同樣,你不應該寫這兩種:

if (greeting == True) == True: 

額外的測試是多餘的,不要爲代碼添加任何值,所以應該刪除它們。

+3

人們無法得到布爾值,這真是太神奇了。例如「bool Predicate(){if(condition)return true; else return false;}」 - 什麼?這可以寫成簡單的「bool Predicate(){return condition;}」! – Asik 2012-04-19 06:28:57

+0

不幸的是,當語言支持真實性/虛假性的其他值時,您使用的確切語句可以徹底改變程序的含義......像'__eq__','__nonzero__'和'__len__'這樣的特殊函數只會讓事情變得更糟,是的,但有時會出現問題) – mgibsonbr 2012-04-19 06:37:33

+2

@mgibsonbr您可以使用'bool'將值強制爲一個布爾值。 – Marcin 2012-04-19 06:38:56

1

因爲它是多餘的。

if hasChildren: 

相同

if hasChildren == True: 

,但簡短,更易於閱讀。

+0

if numberOfChildren:如果答案不爲零,那麼print True將返回true。即使它是負面的。隱式轉換爲布爾值具有副作用,通常不鼓勵。然而,風格指南鼓勵隱式轉換爲布爾。 – 2012-04-19 13:44:43

+0

@PeterMoore,你誤解了風格指南。 '如果numberOfChildren> 0:'完全是pythonic,但是if(numberOfChildren> 0)== True:'不是。 – 2012-04-23 06:29:39

+0

@Bago我完全同意if(numberOfChildern> 0)== True:是多餘的,因爲比較器「>」將明確地使左側爲布爾類型。但是,如果使用unknown_type:與樣式指南相反,則不如使用「is」進行測試安全。測試bool「是」bool比bool更好:或者如果bool == bool:因爲在python中發生的真值重載,你不會得到一個false真。我真的在說什麼。 – 2012-04-23 14:47:36

2

恕我直言,指導風格的一點是要以一種合理的方式來標準化一些常見的結構,所以你最終不會做出最終會做同樣事情的非常不同的陳述。更多的是,這些不尋常的形式可能表明程序員有理由以不同的方式做事,也許他試圖實現與陳述不同的東西。

如果您想測試陳述的真實性/虛假性,只需使用陳述本身或在not之前。如果您必須確保該聲明的評估結果爲TrueFalse(不僅僅是真/假值),您可以使用statement is True - 雖然樣式指南不鼓勵它或者檢查其類型(使用isinstance)。但這通常是不好的設計,除非你有充分的理由這樣做,否則你應該避免這種情況。

使用statement == True是有危險的,原因很多:1)僅適用於True,與其他「真值」(例如[1])失敗; 2)如果語句返回的值重新定義了__eq__,則可能會產生意想不到的結果; 3)如果參數的順序改變等,可能會產生不同的結果。請注意,如果值實現__nonzero____len__,則僅使用該語句也可能返回不同的真實/虛假值,但對於常規使用而言通常不會造成問題。

一些例子,說明如何搞砸事情都可以,如果你從風格偏離:

if True: print True # True 
if 1: print True # True 
if [1]: print True # True 

True is True # True 
1 is True # False 
[1] is True # False 

True == True # True 
1 == True # True 
[1] == True # False 

編輯:一些:

if 1: print True # True 
if 2: print True # True 

1 == True # True 
2 == True # False 

1 is True # False 
2 is True # False 

更新:爲@Marcin指出,您可以使用bool將值強制爲True/False,保證只有這些值纔會出現。該函數的結果與該值的默認真實/虛假性一致(因此將__nonzero____len__考慮在內)。一些例子:

if bool(1): print True # True 
bool(1) == True  # True 
bool(1) is True  # True 

if bool(2): print True # True 
bool(2) == True  # True 
bool(2) is True  # True 

1 or 2    # 1 
1 and 2    # 2 
bool(1) or bool(2) # True 
bool(1) and bool(2) # True 

bool(1) == bool(2) # True 
bool(1) is bool(2) # True 
+0

我很欣賞你的意見,這是一個明確的轉換。我的牛肉(因爲它在哪裏)是風格指南鼓勵我認爲馬虎的副作用通過嚴格的顯式轉換隱含轉換的地方。我不認爲(例如)一個容器是真或假。對我來說,重載一個這樣的真理意味着它不是空的是沒有多大意義的。 – 2012-04-19 14:41:59

+0

這是主觀的恕我直言,某些語言(如Java)鼓勵以明顯的轉換爲理由,減少錯誤的窗口,其他語言鼓勵DWIM行爲以增加語言表達能力。在C語言中將數字視爲假/真,如果它們爲零/非零是常見做法,將空容器(列表,字符串和集合)視爲false在Lisp中很常見,並且這兩種做法都有優點和缺點。重要的是語言要一致地實施所選擇的策略(對比JavaScript,例如,「」是錯誤的,但[]是真實的)。 – mgibsonbr 2012-04-19 23:39:20

+0

我不認爲使用bool(unknown_type)會有與使用unknown_type「is」[False | True]相同的效果,例如如果T = -1那麼它不是True,按照約定0 = False 1 = True並且type是一個bool。所以測試在布爾狀態測試中給出了錯誤的結果。 – 2012-04-23 15:20:48

0

在排序:

# A, Good: 
if numberOfApples > 0: 
    print "you have apples" 

# B, Also good: 
iHaveApples = numberOfApples > 0 
if iHaveApples: 
    print "you have apples" 

# C, Bad: 
iHaveApples = numberOfApples > 0 
if iHaveApples == True: 
    print "you have apples" 

爲什麼你會永遠挑下在A或B?

更新:

我想你出汗多一些極端情況的子彈,但如果這些極端情況在您的項目無論用適當的比較。一般來說,我們知道iHaveApples的類型,例如我們知道這是使用>進行比較的結果。我相信,在代碼中使用這些信息是合理的,也是一種很好的做法。如果你問,「如果我認爲這是一個傻瓜,結果是一個整數或其他東西。」比我想說的你的代碼中有一個bug,你應該找到它,修正它,並寫一個測試,以防再犯同樣的錯誤。不要依靠python在運行時找到你的錯誤。

我就斷言,並留下你來證明,如果你想,那if iHaveApples:的行爲完全一致,但運行速度更快,因爲if iHaveApples is True:當你知道肯定iHaveApples是一個布爾值。最後,我會舉例說明is何時會導致不良行爲,至少在我看來。

>>> import numpy 
>>> totalApples = numpy.sum([1, 2, 3]) == 6 
>>> totalApples 
True 
>>> totalApples is True 
False 

我會讓你找出原因,如果你想(提示,檢查type(totalApples))不起作用。

+1

我認爲C也不是很正確,但它應該是「是」而不是==。所以如果iHaveApples是真的比任何其他表達方式更真實。我絕對不認爲它應該是風格指南吸取的方式。 – 2012-04-23 14:13:43

+1

順便說一下B不好,除非你知道你正在比較一個布爾值。你怎麼知道這個類型在if語句中是一個bool?如果你認爲你比較一個bool而不是bool,那麼隱式轉換問題只會提高它的頭。這就是爲什麼我選擇-1的numberOfApples爲我的例子。還有爲什麼我用> comparitor做了一個布爾值。樣式指南正在討論顯式測試布爾值,並且其測試不夠安全。 – 2012-04-23 16:13:10

+0

@PeterMoore,看我的更新 – 2012-04-24 01:20:35