Pythonのブール値にはまる

Pythonでは、偽として、None、False、0(数値のゼロ)、空のシーケンス型、空のマッピング型などがある。
これを知らなくて、関数の引数として、数値を入力させて、不要な場合は、Noneを入れる仕様にしていたのだが、数値がたまたま、0となっているのに気づかず、Noneでない値を入れているのにif文で条件がスキップされるので、思った通りの動作にならずに、おかしいなーと思って、はまってしまった。


Rubyでは、nilかfalse以外の値は全て真なので非常にシンプルであるが、Pythonの偽は複雑で、シンプルな仕様のPythonらしくない気がする。
また、Pythonでは、if文などの真偽判定はいわゆるブール型(とNone)以外も許すため、私がはまったようなミスをしやすいと言える。


# a == bを間違えて、a = bと書いてもエラーにならず通ってしまう。
# もし、aが0以外で、bが0なら混乱のもと。
if a = b:
print 'ok'

言語仕様が良くないとは言え、True、falseも後付なので互換性を保つためにはしょうがない。


追記:
上の例は、私の間違いでした。


if a = b:
print 'ok'

は、コンパイルエラーになります(バージョン2.4.3で確認)。


私が実際はまった例としては、


def foo(num, val):
if num and num > val:
print 'ok'

のようなケースで、if文を判定をパスする場合は、Noneを入れるようにしていたのだが、たまたま、numが0となり、判定されていなかったというミス。
完全に勘違いをしていたが、上記がなぜエラーになるかは、まだ理解できていないので調べてみよう。