19

Python PEP 8の終わりに、私は読んでいます:

  • を使用してブール値を True または False と比較しないでください。==

     Yes:   if greeting:
     No:    if greeting == True:
     Worse: if greeting is True:
    

ブール値が の場合、その推奨事項に問題はありませんがTrue、 をチェックすると奇妙に聞こえFalseます。

変数の挨拶が False かどうかを知りたい場合、次のように記述しないのはなぜですか?

    if greeting == False:

私が書くif not greeting:と、上記のステートメントとは非常に異なる意味になります。挨拶がなしの場合は?空の文字列の場合はどうなりますか? この PEP 8 の推奨事項は、ブール値を格納する変数に True または False のみを含める必要があり、これらの変数に対して None を避ける必要があることを意味しますか?

私の目には、静的型付けを使用する他の言語からの推奨事項のように見えますが、少なくとも False と比較すると、Python にはうまく適合しません。

ところで、なぜ がif greeting is True:よりも悪いと説明されているのif greeting == True:ですか? if greeting is False:それもそれよりも悪いことも理解する必要がありif greeting == False:ますか?

4

6 に答える 6

18

読み方が間違っていると思います。名詞を動詞と同じように考えないようにしてくださいgreeting(「This is a greeting」ではなく「I am greeting」)。

PEP8 のプリアンブルに手がかりがあります。

Guido の重要な洞察の 1 つは、コードは書かれるよりも読まれることが多いということです。ここで提供されるガイドラインは、コードの可読性を向上させることを目的としています。

そのために、コードは可能な限り書き言葉や話し言葉に似ている必要があります。あなたは"If I am annoying you is true, let me know"実生活では言いません、ただ言うだけ"If I am annoying you, let me know"です。

これが、コードの可読性に役立つため、isOpenや などのブール変数がよく見られる理由の 1 つです。hasBeenProcessed

次のようなことは絶対にしないでください。

if (isOpen == True)

また:

if (customerDead == False)

変数名にブール値が既に含まれているためです。平等があなたに与えているのは、別のブール値です。

if (isComplete == True) ...
if ((isComplete == True) == True) ...
if (((isComplete == True) == True) == True) ...
if ((((isComplete == True) == True) == True) == True)...
于 2010-10-29T09:33:33.063 に答える
6

==または比較を介して真実を比較しない最も単純な理由は次の!=ようです。

0 is False # Result: False
0 == False # Result: True; 0 evaluates comparatively to False

1 is True  # Result: False
1 == True  # Result: True; 1 evaluates comparatively to True

is渡された値が正確に True/Falseであるかどうかをチェックし、 または に評価れるかどうかをチェックします。TrueFalse

この動作により、次のことが可能になります。

if var is False:
   # False (bool) case
elif var is None:
   # None case
elif var == 0:
   # integer 0 case

一方

if var == False:
    # catches False & 0 case; but not None case, empty string case, etc.

これは直感に反しているように思えます。これが、PEP 8 が「やらないでください」と言っていると私が予想する理由です。

ここで述べたようisに、アイデンティティには使用==しますが、平等には使用します。

if var is Trueブール値が必要な場合にのみ使用したいが、True拒否したい場合など.1'some string'

このようなケースは、おそらくほとんどの読者には明らかではありません。PEP 8 は、誤解を招く可能性があるため「悪い」と主張しているのではないかと思います。時々、それは必要悪かもしれません。しかし... が必要な場合は、設計上の問題を示してis Trueいる可能性があります。いずれにせよ、「なぜ」正確に True必要なのか、または使用したことがあるかFalseどうかをコメントする必要がありますis

于 2015-04-30T00:27:47.483 に答える
5

これはダックタイピングの一部です。Python では、通常、受け入れるものを特定のクラスに制限するのではなく、適切な API を公開するオブジェクトに制限したいと考えています。たとえば、私はこれを行うことができます:

class MyProperty(object):
    """
    A file-backed boolean property.
    """
    def __init__(self, filename):
        self.value = open(filename).read()
    def __nonzero__(self):
        return self.value != "0"
    def save_to_disk(self):
        # ... and so on
        pass

def func(enabled):
    if not enabled:
        return
    # ...

enable_feature = MyProperty("enable_feature")
func(enable_feature)

と言うif enabled == Falseと、これが機能しなくなります。

False はfalse値ですが、それだけがfalse 値ではありません。を使用しないのと同じ理由で、True と False を比較することは避けてくださいisinstance

于 2010-10-29T09:24:51.580 に答える
4

私が理解しているように、PEPの推奨事項は、タイプを合理的に確信できる場合foo(通常はそうです)、明示的なfalse値のテストは冗長であり、読みやすさを低下させることを意味します。たとえば、では、false値のみが持つことがfoo = [i for i in range(10) if i == x]できることをかなり確信で​​きます(例外が発生しないと仮定)。この場合、使用するのは冗長であり、より優れています。foo[]foo == []not foo

一方、foo == []またはのセマンティック値は、foo == Falseより価値がある場合があり、の代わりに使用する必要があります(IMHO)not foo。具体的には、何を伝えようとしているのかによって異なります。実際にnot foo 「偽の値がありますか?」をfoo意味ますが、「?と同じ値があります」を意味します。foo == False fooFalse

PEPは、含まれているものはすべてガイドラインであると述べています。ルールには例外があり、これも例外ではありません。

于 2010-10-29T10:22:51.233 に答える
1

他のコメントがあなたの質問に答えたかどうかはわかりません。あなたは言う:

私が書くif not greeting:と、上記のステートメントとは非常に異なる意味になります。挨拶がなしの場合は?空の文字列の場合はどうなりますか?

確かに、not greetinggreeting == Falseは異なる意味を持ちます。しかし、PEP 8 は反対のことを言っているわけではなく、使用しないように言っているわけでもありませんgreeting == False。それは言います:

== を使用してブール値を True または Falseと比較しないでください

None空の文字列もブール値ではありません。したがってgreeting == False、適切な場合に使用し、greeting非ブール値にすることができます。


誰かがあなたの質問の下にコメントしました:

...なぜ、None になることもあれば、bool になることもあるし、str になることもあるのですか? それは、あらゆる種類のトラブルを求めているだけです。

そうではありません。ユースケースは次のとおりです。患者が自殺で死亡したかどうかを示すフィールドを持つ患者のデータベースがあります。Patientattributeを持つクラスがあるとしましょうsuicidesuicide可能な値は次の 3 つです。

  • True「はい、私たちは彼が自殺したことを知っています」という意味です
  • False「いいえ、私たちは彼が別の原因で亡くなったことを知っています」
  • None「実際にはわからない」という意味です。

次に、自殺で死亡していない患者を調べたい場合は、次のようにします。

# load database
...

# Filter patients
database = [patient for patient in database if patient.suicide == False]  # if greeting == False:

# Study database
...

QED。これは、データ サイエンスの典型的なケースです。値Falseとは、何かが間違っていることを知っていることを意味しますが、値Noneとは何も知らないことを意味します。

于 2019-08-23T17:34:34.877 に答える
0

私は通常、パターンの後にブール変数に名前を付けます。IsNameしたがって、あなたの場合はIsGreeting. これにより、チェックがif IsGreeting/if not IsGreetingになり、非常に直感的になります。

あなたが説明しているあいまいさはif not、ブール比較で非ブール型を使用した結果です。これは非常に紛らわしいので、通常は避けるべきです。

于 2010-10-29T08:54:47.767 に答える