'' と None は違うのだ
Python のイディオムで、こういうのがある。
f = open('file.txt') whlie 1: line = f.readline() if not line: break process(line)
これは、ファイルの終端(EOF)になると readline() が '' (空文字列) を返し、'' は論理値を期待する文脈で False と解釈されることを利用している。ちなみに None も同じ状況で False と解釈されるので、ちょっとした誤解が生じる(かも知れない)。
というのは、あくまでも EOF で readline() が返すのは '' であって、None や False ではないのだ。以下の条件式は絶対に True にならない。(ここで、'/dev/null' は Unix で常に EOF を返す特殊ファイル。)
>>> '' == False False >>> None == False False
しかし、論理値を期待する文脈では False として解釈されるので、次は True になる。
>>> not '' True >>> not None True
知っている人には当たり前かも知れないが、マニュアルをよーく読まないと失敗するはめになる。注意しよう。ちなみに蛇足だが、1 と True、0 と False はほとんどの文脈で等価だ*1。だから、次は True になる。
>>> 1 == True True >>> 0 == False True
しかし、組込関数*2 type() を適用すると、これらは区別される。
>>> type(True) <type 'bool'> >>> type(1) <type 'int'> >>> type(None) <type 'NoneType'> >>> type('') <type 'str'>
気をつけよう。
file 型補足
通りがかりの人に、Python 2.2 以降では file 型がイテレータ(iterator)になっているので、次のように書いたほうが便利だと教えて頂きました。
f = open('file.txt') try: for line in f: process(line) finally: f.close()
ちなみに、for line in open('file.txt'): と書くと明示的なクローズができなくなるので、厳密には上のように書いたほうが良いようです。Python 2.6 以降で(あるいは 2.5 で from __future__ import with_statement した場合)は、
with open('file.txt') as f: for line in f: process(line)
のようにすることで、with 文から抜けるとファイルが自動的にクローズされるのだそうですが、なんだか全然分からん。
type() 補足
ちなみに、type(a) で a の型(a に代入されている型)が分かると書きましたが、コード中で a の型によって処理を分岐したり例外を上げたりしたいとき、isinstance() という組込関数が使えます。
>>> a = '' >>> if isinstance(a, str): ... print "string" ... elif isinstance(a, int): ... print "integer" ... else: ... print "other type" ... string
ちなみに、isinstance(type, type) == True のようです。また、None かどうかの比較に isinstance(a, none) とかは書けないようで、a == None、とするしかないようです。(リファレンスマニュアルによると、None の型は唯一の値である None しか持たないということなので、これで良いのでしょう。)