会社のSlackでの1コマ
Pythonのor
やall
で、式の評価を途中でやめてくれない
>>> print('a') or pring('b') a b
↑の場合、直感的にはb
は出力されないはずだけど、バッチリでてる
Pythonって正格なのか、、?と思うも、
>>> 0 and print('b') 0
こっちだとor
は非正格に見える
この差異はprint
の返り値がNone
のために起きてる
Noneの真偽値は、False
>>> bool(None) False
なので、↑のケースでprint
の結果にTrue
を期待してると、裏切られると言う訳
次にall
print
がFalse
に評価されることを踏まえて、
def a(): print('a') return True def b(): print('b') return False def c(): print('c') return True
とすると
result = all([a(), b(), c()]) print(result) result2 = (a() and b() and c()) print(result2) a b c False a b False
という結果になる
and
は非正格だけど、all
は正格に見えてしまう
これにもタネがあって、↑のa,b,c
はall
実行時ではなく、リスト生成時に出力されているから
>>> [a(), b(), c()] a b c [True, False, True]
こんな感じ
なので、改めてall
を検証すると
class A: def __bool__(self): print('a') return True a = A()
とすると、
>>> all([True, a, False, a]) a False
となって、all
は非正格なことが確認できた