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():
passasynccontextmanager
非同期コードでは、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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- with 文を深く理解する
- __enter__ と __exit__ プロトコル
- contextlib: @contextmanager
- 実践的なコンテキストマネージャーパターン