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