【Python】クラスをwith文で使う方法【コンテキストマネージャ】

Python

この記事では、Pythonのクラスをwith文で使えるようにする方法を解説します。with文でクラスを使うことで前処理と後処理を安全に実行することができます。

コンテキストマネージャを定義するには

クラスに、以下の2つの特殊メソッドを定義します。

__enter__(self)

このメソッドは、with文のコードブロックを処理する前に実行されます。

__exit__(self, exc_type, exc_value, traceback)

このメソッドは、with文のコードブロックを抜ける際に実行されます。引数には、コードブロック内で例外が発生した際のデータが格納されます。例外が発生しなかった場合はNoneが格納されます。

定義してみる

自作クラスにコンテキストマネージャを定義してwith文で使ってみます。

class ContextManager:

    def __enter__(self):
        print('前処理')

    def __exit__(self, exc_type, exc_value, traceback):
        print('後処理')


with ContextManager():
    print('with文のコードブロック内')

実行結果

前処理
with文のコードブロック内
後処理

asを使う場合

asで生成した変数には__enter__メソッドの戻り値が渡されます。

サンプル

以下のように、__enter__メソッドに戻り値を定義することで、asで生成した変数に戻り値を渡すことができます。

class ContextManager:

    def __enter__(self):
        print('前処理')
        return '__enter__の戻り値です'  # 戻り値を定義

    def __exit__(self, exc_type, exc_value, traceback):
        print('後処理')


with ContextManager() as text:
    print(text)

実行結果

前処理
__enter__の戻り値です
後処理

例外が発生した場合

with文のコードブロック内で例外が発生しても、__exit__メソッドは実行されます。

サンプル

ブロック内で例外を発生させて__exit__メソッドが処理されるか確認してみましょう。ついでに、引数にどのような値が格納されているか出力してみます。

class ContextManager:

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_value, traceback):
        print(exc_type)
        print(exc_value)
        print(traceback)


with ContextManager():
    # 例外を故意に起こす
    raise ValueError('エラー発生')

実行結果

<class 'ValueError'>
エラー発生
<traceback object at 0x1054eab40>

まとめ

この記事では、Pythonのクラスをwith文で使えるようにするための方法解説しました。

今回のおさらい

  • 前処理: __enter__(self)
  • 後処理:__exit__(self, exc_type, exc_value, traceback)

クラスをコンテキストマネージャにすることで、とても強力に前処理と後処理を定義することができます。とくに後処理は、途中で例外が発生した場合でも実行してくれるので、必ず後始末をすることができます。

実装する機会はあまり無いかもしれませんが、選択肢の1つとして覚えておきましょう!

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ

【Python】デコレーターを使って関数を修飾する【Python】デコレーターを使って関数を修飾する

タイトルとURLをコピーしました