web-dev-qa-db-ja.com

なぜ `if None .__ eq __(" a ")`がTrueと評価されるように見えるのですか(完全ではありません)?

Python 3.7)で次のステートメントを実行すると、(私のテストから)bが出力されます。

_if None.__eq__("a"):
    print("b")
_

ただし、None.__eq__("a")NotImplementedに評価されます。

当然、"a".__eq__("a")Trueに評価され、"b".__eq__("a")Falseに評価されます。

関数の戻り値をテストするときに最初にこれを発見しましたが、2番目のケースでは何も返しませんでした。そのため、関数はNoneを返しました。

何が起きてる?

145

あなたが見ている結果は、その事実によって引き起こされます

_None.__eq__("a") # evaluates to NotImplemented
_

NotImplementedに評価され、NotImplementedの真理値はTrueであると文書化されています。

https://docs.python.org/3/library/constants.html

バイナリの特別なメソッドによって返される特別な値(例:__eq__()__lt__()__add__()__rsub__()など)操作が他のタイプに関して実装されていないこと。同じ目的で、インプレースバイナリ特殊メソッド(たとえば、__imul__()__iand__()など)によって返される場合があります。 その真理値は真です。

単に_==_を使用するのではなく、手動で__eq()__メソッドを呼び出す場合、NotImplementedが返され、その真理値がtrueになる可能性に対処する準備が必要です。

33
Mark Meyer

すでに考えたように、None.__eq__("a")NotImplementedと評価されますが、

_if NotImplemented:
    print("Yes")
else:
    print("No")
_

結果は

はい

これは、NotImplementedtrueの真理値

したがって、質問の結果は明らかです。

None.__eq__(something)NotImplementedを生成します

bool(NotImplemented)はTrueと評価されます

if None.__eq__("a")は常にTrueです

16
Kanjiu

どうして?

NotImplementedを返します。

>>> None.__eq__('a')
NotImplemented
>>> 

しかし、これを見れば:

>>> bool(NotImplemented)
True
>>> 

NotImplementedは実際には真の値であるため、bを返すのはTrueであるものはすべて通過し、Falseであるものはすべて通過しません。

解決方法

Trueであるかどうかを確認する必要があるため、次のように、より疑わしいものにしてください。

>>> NotImplemented == True
False
>>> 

だからあなたがするだろう:

>>> if None.__eq__('a') == True:
    print('b')


>>> 

そして、あなたが見るように、それは何も返しません。

1
U10-Forward