Python でコンテキスト マネージャーを使用する方法 (ステートメントあり)

Python でコンテキスト マネージャーがどのように機能するかを学びます。 with ステートメントをマスターし、システム リソースを管理し、カスタム コンテキスト マネージャーを作成します。

エディターでこのソリューションを試してください

概要

ファイル ハンドルを閉じる、データベース接続を切断する、スレッド ロックを解放するなど、外部リソースを適切に管理することは、信頼性が高く実稼働対応のソフトウェアを構築するために不可欠です。リソースの解放に失敗すると、メモリ リーク、ファイル ロック エラー、アプリケーションのハングが発生する可能性があります。

Python の「with」ステートメントは、コンテキスト マネージャーを作成することでリソースのクリーンアップを簡素化します。コンテキスト マネージャーは、コードが例外をスローしたり早期に終了したりしても、コントロールがブロックを離れるときにクリーンアップ アクションが自動的に実行されることを保証します。これにより、冗長で反復的な `try-finally` ブロックが不要になります。

コンテキスト マネージャーは一般的に「open()」などの組み込み操作に関連付けられていますが、独自のカスタム コンテキスト マネージャーを簡単に設計できます。これらを構築するには、`__enter__` および `__exit__` マジック メソッドを実装するクラスを作成するか、`contextlib.contextmanager` デコレーターで装飾されたジェネレーター関数を作成します。

コードと実行の出力

このスクリプトは、クラス実装と contextlib デコレーターを使用して Python でカスタム コンテキスト マネージャーを作成する方法を示します。

from contextlib import contextmanager

# Method 1: Class-based context manager
class CustomResource:
    def __enter__(self):
        print("[Resource] Opening connection...")
        return self

    def do_work(self):
        print("[Resource] Performing action...")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("[Resource] Closing connection safely.")
        return False

print("--- Class Context Manager ---")
with CustomResource() as resource:
    resource.do_work()

# Method 2: Generator-based context manager (contextlib)
@contextmanager
def simple_timer():
    print("\n[Timer] Started...")
    try:
        yield
    finally:
        print("[Timer] Finished!")

print("\n--- Decorator Context Manager ---")
with simple_timer():
    print("Performing tasks inside context...")
端子出力
--- Class Context Manager ---
[Resource] Opening connection...
[Resource] Performing action...
[Resource] Closing connection safely.

--- Decorator Context Manager ---

[Timer] Started...
Performing tasks inside context...
[Timer] Finished!

段階的な実装

  • ファイル、データベース、またはロックを開くときに with ステートメントを使用して、リソースの安全性を保証します。
  • __enter__ および __exit__ マジック メソッドを持つクラスを使用して、カスタム コンテキスト マネージャーを定義します。
  • よりシンプルな関数ベースの代替手段として、ジェネレーター関数で @contextlib.contextmanager デコレーターを使用します。
  • エラーが発生した場合でも確実に実行されるように、リソースを閉じるアクションをクリーンアップ ブロック内に配置します。

よくある質問

__exit__ メソッドはどのようなパラメータを受け取りますか?

__exit__ メソッドは、例外が発生した場合にその詳細を表す 3 つの引数、exc_type (例外のタイプ)、exc_val (例外値)、および exc_tb (トレースバック) を受け取ります。エラーが発生しなかった場合、3 つすべてが None として渡されます。

コンテキストマネージャーは例外を抑制できますか?

はい。 __exit__ メソッドが真実の値 (True など) を返した場合、Python は例外を抑制し、with ブロックの後も実行を続行します。 False が返された場合、例外は通常どおり発生します。

関連トピック

推奨される Python リソース

関連するインタラクティブなチュートリアル、チートシート、コード比較で知識を深めてください。