0Pricing
Python Academy · レッスン

contextlib: @contextmanager

contextlib デコレーターでコンテキストマネージャーを簡潔に作成します。

「contextlib: @contextmanager」はCoddyKit上の無料Python Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPython Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Python Academyコースには全4レッスンが含まれています。

contextlibを使う理由

contextlib.contextmanagerを使うと、クラスではなくジェネレーター関数としてコンテキストマネージャーを記述でき、定型コードを減らせます。

from contextlib import contextmanager

@contextmanager
def managed():
    print("setup")
    yield
    print("teardown")

with managed():
    print("inside")

値の生成

yieldした値は、with文のas変数にバインドされます。

from contextlib import contextmanager

@contextmanager
def temp_list():
    lst = []
    yield lst
    print(f"Final list: {lst}")

with temp_list() as lst:
    lst.append(1)
    lst.append(2)

@contextmanagerでの例外処理

例外が発生しても必ずクリーンアップされるように、yieldをtry/finallyで囲みます。

from contextlib import contextmanager

@contextmanager
def safe_open(path):
    f = open(path)
    try:
        yield f
    finally:
        f.close()

with safe_open("data.txt") as f:
    print(f.read())

例外の抑制

例外をジェネレーター内で捕捉して抑制します。これは__exit__からTrueを返すのと同じです。

from contextlib import contextmanager

@contextmanager
def ignore_value_errors():
    try:
        yield
    except ValueError:
        pass

with ignore_value_errors():
    raise ValueError("ignored")

contextlib.suppress

contextlib.suppress(*exceptions)は、指定した例外型を抑制する、すぐに使えるコンテキストマネージャーです。

from contextlib import suppress

with suppress(FileNotFoundError):
    open("missing.txt")

print("continues")

contextlib.closing

closing(obj)は、終了時にobj.close()を呼び出すコンテキストマネージャーを作成します。close()はあるものの__exit__がないオブジェクトに便利です。

from contextlib import closing
from urllib.request import urlopen

with closing(urlopen("https://example.com")) as page:
    content = page.read()

contextlib.nullcontext

nullcontextは何もしないコンテキストマネージャーです。コンテキストマネージャーがオプションの場合に便利です。

from contextlib import nullcontext

def process(data, lock=None):
    cm = lock if lock is not None else nullcontext()
    with cm:
        return [x*2 for x in data]

contextlib.ExitStack

ExitStackを使うと、数が変動するコンテキストマネージャーを動的に管理できます。

from contextlib import ExitStack

files = ["a.txt", "b.txt", "c.txt"]
with ExitStack() as stack:
    handles = [stack.enter_context(open(f)) for f in files]
    data = [h.read() for h in handles]

@contextmanagerの再利用

ジェネレーターをベースとするコンテキストマネージャーは、呼び出しごとに1回だけ使用できます。再利用するには、デコレートされた関数をもう一度呼び出します。

from contextlib import contextmanager

@contextmanager
def counter():
    count = 0
    yield lambda: count.__add__  # each call is independent
    print("done")

with counter():
    pass
with counter():
    pass

asynccontextmanager

非同期コードでは、contextlib.asynccontextmanagerを使うと、ジェネレーターとしてasync withマネージャーを記述できます。

from contextlib import asynccontextmanager

@asynccontextmanager
async def async_session():
    session = await create_session()
    try:
        yield session
    finally:
        await session.close()

contextlib.redirect_stdout

標準出力を、任意のファイル風オブジェクトに一時的にリダイレクトします。

import io
from contextlib import redirect_stdout

buf = io.StringIO()
with redirect_stdout(buf):
    print("captured")

print(buf.getvalue())  # captured

クイックチェック

@contextmanagerのジェネレーターで、例外が発生してもクリーンアップを必ず実行するには、クリーンアップコードをどこに配置しますか?

まとめ

@contextmanagerは、ジェネレーターをコンテキストマネージャーに変換します。安全にクリーンアップするには、yieldをtry/finallyで囲みます。contextlibモジュールには、suppress、nullcontext、ExitStackなども用意されています。

よくある質問

「contextlib: @contextmanager」レッスンは無料ですか?

はい。「contextlib: @contextmanager」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Python Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Python Academyコースには全4レッスンが含まれています。

「contextlib: @contextmanager」で何を学びますか?

contextlib デコレーターでコンテキストマネージャーを簡潔に作成します。 ブラウザで直接実行するハンズオンコードでPython Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Python Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPython Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「contextlib: @contextmanager」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPython Academyレッスンでコードを書いて実行できますか?

はい。すべてのPython Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. with 文を深く理解する
  2. __enter__ と __exit__ プロトコル
  3. contextlib: @contextmanager
  4. 実践的なコンテキストマネージャーパターン
← Python Academyに戻る