トップ 一覧 検索 ヘルプ RSS ログイン

ファイルIO.pyの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
{{category Python}}
!!! open()
!! 基本
組み込みopen()関数を使う。

 f = open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)

file はファイルパスを表す文字列。

modeオプションは文字列として指定:
r: 読み取り専用。オプションが指定されない場合は、rが指定されたとみなされる。
w: 書込み専用。
a: 追加書込み。
r+: 読み取りと書込み。
b: バイナリモード。

bオプションを指定しないとテキストモードでファイルを開く(ファイルのエンコードはデフォルトか、プログラマがencodingパラメータで指定のいずれか)。エンコードが正しくないとUnicodeDecodeErrorが発生。

bオプションを指定すると、これまでどおりバイナリモードで開く。
読み込まれたデータはbytesとして扱う。

close()は

 f.close()

ついclose(f)とやってエラーになる。。。

!! open()時のファイルエンコード
encoding引数を指定しないと、OSデフォルトのエンコーディングでファイルが開かれる。
Python 3からは、処理対象エンコーディングを明示的に指定しないと、UnicodeDecodeErrorが吐かれる。
Python 3からは、指定したエンコーディングと実際のファイルの文字コードが合致していないと、UnicodeDecodeErrorが吐かれる。

しかし例えば、テキストログ中に非文字コードパターンが含まれているファイルなど、エンコーディングをどうしても指定できないファイルを、その他の部分は通常のテキストファイルとして処理しなければならない場合がある。

そんなときは、errors引数に"ignore"と指定する。

 f = open(file_path, errors="ignore")

デコードエラーが単に無視される。
"ignore"はデータロスを引き起こすかもしれない、とのこと。

!!! open()が返すオブジェクト
テキストモードで開いた場合、_io.TextIOWrapper クラスのインスタンス(type()で見える)。
これは、イテレータとして扱える。

 f = open("/var/log/messages")
 for l in f:
     ...

直感的にテキストストリームが返ってくる。
ラインはそのまま返されてくるので、改行コードは付いたまま返ってくる。

!!! with
with文を使うと、ファイルオープンの try/except/finally を簡単に書ける。
with文はブロックを生成し、ブロックを抜けると as のオブジェクトを始末する。

 with open('C:/targetfile.txt') as f:
     lines = f.readlines()
 
 # withブロックを抜けると、fは自動的にクローズされている。

もし、ファイルをオープンしてさらにファイルハンドルをいろいろ処理するのであれば、try/except/finally で制御した方がいいのだが、この例のように中身を得たらすぐにファイルを閉じるだけ、という場合には、try/except/finally よりも簡潔に書ける。

PEP343によると、以下が with 文が実現することである、とのこと。

 mgr = (EXPR)
 exit = mgr.__exit__  # Not calling it yet
 value = mgr.__enter__()
 exc = True
 try:
     try:
         VAR = value  # Only if "as VAR" is present
         BLOCK
     except:
         # The exceptional case is handled here
         exc = False
         if not exit(*sys.exc_info()):
             raise
         # The exception is swallowed if exit() returns true
 finally:
     # The normal and non-local-goto cases are handled here
     if exc:
         exit(None, None, None)

おおー、なるほど!