猫型エンジニアのブログ

プログラム/ネットワーク系の技術関連をまとめたページです 

contextlibモジュール

Pythonでファイルの読み書き

 以下のようにしてファイルの読み書きができます。

# -*- coding: utf-8 -*-

if __name__ == "__main__":

    f = open("test.txt","w")
    f.write("Pythonでファイルを開きました")
    f.close()

    f = open("test.txt","r")
    for row in f:
        print row
    f.close()

 実行結果

$ python test.py 
Pythonでファイルを開きました

with構文

 明示的のファイルのオープンおよびクローズを行っていますが、with構文では以下のように書くことができます。

# -*- coding: utf-8 -*-

if __name__ == "__main__":

    with open("test.txt","w") as f:
        f.write("Pythonでファイルを開きました")

    with open("test.txt","r") as f:
        print f.read()

 with構文では__enter__や__exit__がクラスに必要

with構文とは何なのか - 年中アイス
ですが、fはそれらを属性にもっています。

>>> import inspect
>>> f = open("test.txt", "r")
>>> hasattr(f, "__exit__")
True
>>> hasattr(f, "__enter__")
True

contextlibモジュール

 それらのメソッドを実装することなく、with構文を利用できるようにするのがcontext libモジュールです。上のようにデコレータ形式で利用できますが、下のように書くこともできます。

from contextlib import contextmanager

@contextmanager
def closing(thing):
    try:
        yield thing
    finally:
        thing.close()
from contextlib import closing
import urllib

with closing(urllib.urlopen('http://www.python.org')) as page:
    for line in page:
        print line