2021年7月29日木曜日

Python の with 句を試してみる

Python の with 句を試してみる

概要

Python の with 句を使うことができるサンプルクラスを作成してみました 使えるようになると便利な機能かなと思います

環境

  • macOS 11.5
  • Python 3.8.3

サンプルコード

class WithSampleUser:
    def __init__(self, name, age=None):
        self.name = name
        self.age = age
        self.tel = None
        self.profile = None

    def gen_profile(self):
        if self.age is None:
            raise
        self.profile = {"name": self.name, "age": self.age, "tel": self.tel}

    def __enter__(self):
        # コンストラクタ以外の初期化処理
        self.tel = '090-1234-5678'
        return self

    def __exit__(self, ex_type, ex_value, trace):
        # エラーが発生した場合
        if ex_value:
            self.name = None
            self.age = None
            self.tel = None
            print("error")
        else:
            print(self.profile)

with WithSampleUser("hawksnowlog", 10) as user:
    user.gen_profile()

with WithSampleUser("hawksnowlog") as user:
    user.gen_profile()

解説

まず必須なのは __entry____exit__ の実装になります with 句に入った場合と出た場合に自動的に呼ばれるメソッドで実装が必須になります

__entry__ 側は初期化的なことを行う感じになります 例えばストリームのオープンやファイル操作などのシリアライズを行います

__exit__ は逆に終了時に呼ばれるのでクローズ処理を行います 開いたものを自動的に閉じるために用意されているメソッドみたいな感じなので終了処理を書きます また __exit__ はエラーが発生した際にも呼ばれます その際にはエラー情報が格納された引数「ex_type」「ex_value」「trace」にエラー情報が格納されています

with 句ないで try catch することで発生したエラーを握りつぶせますがあまり with 句内で try catch することはないのかなと思います

想定ユースケース

以下のようなケースで with 句用にクラスをカスタマイズすると良いかなと思います

  • ファイル操作を行うクラス
  • データベース操作を行うクラス
  • HTTP など外部通信を行うクラス
  • ソケットなどのコネクションを確立するクラス

要するに open -> close の流れが必要になるオブジェクトを扱うクラスの場合には with 句で扱えるように拡張するのが良いかなと思います

0 件のコメント:

コメントを投稿