2012-04-19 9 views
5

スタイルガイドhttp://www.python.org/dev/peps/pep-0008なぜ真==:

の最後のポイントは、Trueまたは==を使用してFalseにブール値を比較しないでください...

を読み込みます。

なぜですか?

編集 ちょうど求めて何イムそれを明確にする(そして、それは、問題自体の指標だ)あなたがあなたのかによっては動作しない場合がありブール値に暗黙的な変換を行っている

if something: 
    print "something is true" 

を書くとき、本当の意味でIMHOこの形式のプログラミングは、それが引き起こす可能性のある副作用のためにお勧めできません。

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がboolではないことがわかります。 –

+0

次に、xがbool()の型であるかどうかを比較し、TrueまたはFalseの場合はそれを比較します。 –

+0

@PedroWerneckまったく同じです。だからスタイルガイドは、bool_typeが[True | False]の場合、最悪の方法はブールをテストするのが間違っていると言います。実際には最良の方法だからです。 –

答えて

7

それはあなたが代わりの

if greeting: 

書くべきことを意味します。同様に

if greeting == True: 

を、あなたがこれを書くべきではありません、次のいずれか

if (greeting == True) == True: 

余分なテストが冗長であり、コードに値を追加しないでください。削除する必要があります。

+3

人々がブール値を取得しない方法は素晴らしいです。例えば ​​"bool Predicate(){if(condition)return true;そうでなければfalseを返す}" - 何?これは単純に "bool Predicate(){return condition;}"と書くことができます! – Asik

+0

不幸にも、言語が真実/偽の他の値をサポートするとき、あなたが使っている正確な文はプログラムの意味を大きく変えることができます... '__eq__'、' __nonzero__'、 '__len__'のような特殊関数は、はい、でも問題はありません) – mgibsonbr

+2

@mgibsonbr値をブール値に強制するには、単に 'bool'を使うことができます。 – Marcin

1

冗長なので、

if hasChildren: 

if hasChildren == True: 

と同じですが、簡潔かつ読みやすいです。

+0

if numberOfChildren:print答えがゼロでない場合、Trueはtrueを返します。たとえそれが否定的であっても。真偽値への暗黙的な変換は副作用があり、通常は推奨されません。しかし、スタイルガイドは暗黙のブールへの変換を奨励しています。 –

+0

@PeterMoore、あなたはスタイルガイドを誤解しています。 if numberOfChildren> 0: 'は完全にpythonicですが、' if(numberOfChildren> 0)== True: 'はそうではありません。 –

+0

@Bagoもし(numberOfChildern> 0)ならば、私は全く同意する== True:コンパレータ ">"が明示的に左側をbool型にするので、冗長です。しかし、もしunknown_type:スタイルガイドに反することは、 "is"を使ったテストよりも安全性が低くなります。 "boolをテストする"は "boolがboolの場合より優れています:またはbool == boolの場合:Pythonで発生する真理のオーバーロードのためにTrueを取得しないためです。私は実際に言っています。 –

2

IMHOスタイルガイドのポイントは、意味のある方法でいくつかの共通の構造を標準化することです。したがって、最終的に同じことをする激しく分かれたステートメントに終わることはありません。さらに、異例の形式は、プログラマが別のやりかたをする理由があるかもしれないと示唆しているかもしれません。おそらく、彼はそのステートメントのようなものを実現しようとしていたかもしれません。

ステートメントの真偽/偽をテストする場合は、ステートメント自体を使用するか、またはそれに先にnotを付けます。ステートメントがTrueまたはFalse(true/falsy値だけではない)であることを確認する必要がある場合は、statement is Trueを使用できます(スタイルガイドでは推奨しませんが、isinstanceを使用して確認できます)。しかし、それは通常悪いデザインです。そうする必要がある場合を除いて、それを避けるべきです。

statement == Trueを使用すると、多くの理由で危険です:1)Trueでのみ動作し、他の "真実"値([1]など)で失敗します。 2)は、statementによって返された値が__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

コメントをいただきありがとうございます。これは明示的な変換です。私の牛肉(どこにいても)は、スタイルガイドが、厳密な明示的な変換よりもむしろ愚かな副作用を起こした暗黙的な変換だと思っているところです。私は(例えば)コンテナが真か偽であるとは考えていません。私にはそれは空ではないことを意味するような真理を過負荷にすることは意味がありません。 –

+0

それは主観的なIMHOですが、いくつかの言語(例:Java)は、ウィンドウがエラーを減らすという論理的根拠と、明示的な変換を促し、言語の表現力を高める目的でDWIMの動作を奨励します。ゼロ/非ゼロであれば、false/trueとして扱うのはC言語では一般的な方法です。空のコンテナ(リスト、文字列、セット)をLispで扱うのは一般的ですが、両方の方法には長所と短所があります。重要なのは、言語が選択された戦略を一貫して実装していることです(たとえば、 ""が偽であるが[]が真である場合など)。 – mgibsonbr

+0

私は、bool(unknown_type)を使用すると、unknown_type "is" [False | True]を使用するのと同じ効果があるとは考えていません。たとえばT = -1の場合、慣習では0 = False 1 = True、タイプはブールです。したがって、テストはブールの状態のテストで誤った結果を与えます。 –

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の上にCを選ぶだろうか?

更新:

私はあなたには、いくつかのコーナーケースの上に弾丸を発汗していると思うが、それらのコーナーケースは、適切な比較を使用するプロジェクトで重要であれば。一般的に、iHaveApplesのタイプについてはわかっています。たとえば、>を使用した比較の結果であることがわかります。コード内でその情報を使用することは合理的であり、私が信じていることです。もしあなたが尋ねるならば、「もしそれがブールだと思うと、それはintや他の何かになるだろう」コード内にバグがあり、同じミスを繰り返した場合に備えて、それを見つけて修正し、テストを書く必要があります。実行時にあなたの間違いを見つけるためにPythonに頼らないでください。

私はif iHaveApples:はまったく同じ動作をしますが、あなたはiHaveApplesがブール値であることを確かに知ったときif iHaveApples is True:として、より速く実行されることを、主張し、必要に応じ証明するためにあなたに任せます。最後に、少なくとも私の意見では、isが望ましくない振る舞いをする例を挙げます。

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

私はあなたが(ヒント、type(totalApples)をチェック)したい場合には動作しない理由を把握せていただきます。

+1

私はCも正しくはないと思っていますが、==ではなく "is"でなければなりません。 iHaveApplesがTrueの場合は、それを表現する他の方法より真実になります。私は間違いなくそれがスタイルのガイドsugests方法でなければならないと思います。 –

+1

ブールを比較していることが分かっていない限り、途中でBがうまくいかない。型がif文のブールであることをどうやって知ることができますか?暗黙的な変換の問題は、boolとboolを比較していると思えば、その頭を上げるだけです。だから私は私の例で-1でnumberOfApplesを選んだのです。なぜ私は> comparitorでbooleanを作ったのでしょうか?スタイルガイドはブール値を明示的にテストすることについて話しており、テストは安全ではありません。 –

+0

@PeterMoore、私の更新を参照してください –

関連する問題