語句の意味
「コンテキスト」という語句はプログラミングを書いてるとよく聞くが、理解が曖昧だったので調べてみた。context managerは、リソースの割り当て、解放を必要なときに行ってくれるもの。
contextは、”状態”と考えるといい。リソースが開いている、トランザクションが実行中などの”状態”を指す。
サンプルソース
まず、contextlibを使う前に以下のソースを考える。
if __name__ == '__main__': with open('test.in') as f: for line in f: print linewith 句を抜けると、ファイルがcloseされるのは知っているけど、どうなってるのか?
以下のように、__enter__と__exit__を実装したクラスを作ると、with句の前後でそれぞれのメソッドが呼ばれる。これをうまく使えば、fileのopen、closeが出来そうなのが分かる。
class HogeContext: def __enter__(self): print "open context..." def __exit__(self, exc_type, exc_value, traceback): print "close context..." if __name__ == '__main__': with HogeContext(): print "hello, world"
それじゃあ、__enter__と__exit__を実装していないクラスだとwith句は使えないのか?
と思うが、それを解決するのがcontextlib。
from contextlib import closing class Foo: def doit(self): print "do something..." def error(self): raise Exception('Foo exception...') def close(self): print "closing..." if __name__ == '__main__': with closing(Foo()) as foo: foo.doit() foo.error()上のようにclosing(obj)はwith句を抜けたときにobj.close()が呼ばれるようなコンテキストマネージャを返す。
でこれ何が嬉しいの?というと、
from contextlib import closing import urllib with closing(urllib.urlopen('http://www.python.org')) as page: for line in page: print lineのように使えて、嬉しい。
より柔軟なコンテキストの管理をしたい場合は、以下のようにデコレータを使ってコンテキストマネージャを作ることもできる。
from contextlib import contextmanager @contextmanager def SomeContext(): print "begin some context..." try: yield finally: print "end some context..." if __name__ == '__main__': with SomeContext(): print "Hello, world." raise Exception()
0 件のコメント:
コメントを投稿