概要
普通、後者のように書くと 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:
は等価ではない。