概要
普通、後者のように書くと linter に怒られるし、こいつコード書けないやつだと思われるリスクをはらんでいる。
しかし Python は演算オーバーロードの機能を持つので、厳密には両者は異なる。
実用上そんなことするか、と思われるかもしれないが、著者は実際に SymPy を使ったコードで観測した。ここでは単純化したコード例を記す。
コード例
class Foo:
def __bool__(self):
return False
def __eq__(self, other):
return True
x = Foo()
上のように定義すると、
if x:
print(1)
else:
print(0)
を評価すると
result
0
となる。一方、
if x==True:
print(1)
else:
print(0)
を評価すると
result
1
となる。
説明
-
if M: ...を評価する場合、まずMを評価してvを得る。つぎにbool(v)を評価してwを得る。この値によって if 文が分岐する。-
vにおいて特殊メソッド__bool__が定義されている場合、bool(v)はv.__bool__()として評価される。
-
- 一方、
if M==True: ...を評価する場合、Mを評価してvを得る。次にv==Trueが評価されてwを得る。-
vにおいて特殊メソッド__eq__が定義されている場合、v==Trueはv.__eq__(True)として評価される。
-
これらのルールにより、__bool__ と __eq__ が異なる振る舞いをするときには if x: と if x==True: は等価ではない。