Python Contextlib
時々、ファイルなどのリソースを使用します。開いて、作業が終わったら閉じるのを忘れます。
これは悪いコーディング方法であり、開いているファイルが多すぎると問題が発生します。これらのリソースが不要になった場合でも、プログラムはそれらを無期限に取得する可能性があります。
この状況はメモリリークを引き起こします。これらを自動的に処理するために、Python にはコンテキストマネージャーがあります。
彼らはリソースの管理を担当します。contextlib
は、with
キーワードを使用してリソース管理のためのユーティリティを提供する Python ライブラリです。
Python のコンテキストマネージャーとして with
ステートメントを使用する
Python では、with
ステートメントがリソースを管理し、例外を処理します。したがって、コンテキストマネージャーとして機能します。
コードが with
ステートメントに達すると、一時的にリソースを割り当てます。以前に取得したリソースは、with
ステートメントブロックの実行が終了すると解放されます。
次のコードでは、ファイルを作成して開きました。with
ブロックで取得されたリソースは、コントロールが with
ブロックの外にあるときに解放されます。
サンプルコード:
with open("file.txt", "w+") as f:
print("File Opened")
出力:
File Opened
プログラムにコンテキストマネージャー機能を含めることもできます。このため、クラスにはメソッド __enter__()
と __exit__()
が必要です。
コンテキストマネージャーのフローを理解するために、コントロールがそれぞれのブロックに転送されるときに実行される print
ステートメントを使用して次のコードを実行しました。
サンプルコード:
class MyContextManager:
def __init__(self):
print("In init method")
def __enter__(self):
print("In enter method")
def __exit__(self, exc_type, exc_value, exc_traceback):
print("In exit method")
with MyContextManager() as m:
print("With block")
出力:
In init method
In enter method
With block
In exit method
Python で Function Decorator @contextmanager
を使用する
コンテキストマネージャーとして関数を作成する別の方法は、関数デコレーター@contextmanager
を使用することです。デコレータは、別の関数を入力として受け取り、その機能を拡張/動作を変更し、別の関数を出力として返す関数です。
このデコレータを使用する場合、個別のクラスまたは __enter__()
および __exit__()
関数を作成する必要はありません。contextlib
モジュールからコンテキストマネージャーをインポートする必要があります。
関数の上にある@contextmanager
を使用します。yield
キーワードは、値/制御を返すために使用される return
ステートメントに似ています。
yield
キーワードの前はすべて __enter__
セクションと見なされ、yield
の後はすべて __exit__
セクションと見なされます。
サンプルコード:
from contextlib import contextmanager
@contextmanager
def MyContextManager():
print("In enter method")
yield
print("In exit method")
with MyContextManager() as m:
print("With block")
出力:
In enter method
With block
In exit method
I am Fariba Laiq from Pakistan. An android app developer, technical content writer, and coding instructor. Writing has always been one of my passions. I love to learn, implement and convey my knowledge to others.
LinkedIn