Pythonでクロージャーを実装する方法

環境

  • Windows 10
  • Python 3.10.1
  • VSCode

使用するソースコード

以下の公開リポジトリに置いています

GitHub - masayan1126/tao-py-py: pythonリポジトリ
pythonリポジトリ. Contribute to masayan1126/tao-py-py development by creating an account on GitHub.

クロージャ―とは

  • 関数Bをラップして返す関数Aがあるとき、関数Bのことをクロージャ―と呼ぶ
  • クロージャを包み込んでいる外側の関数(エンクロージャー)は処理結果を返すのではなく、内側の関数(クロージャ)をオブジェクトとしてreturnする
  • エンクロージャーで定義したローカル変数や引数をクロージャ―内で受け取って使用することができる
  • Scalaでは、Loan Pattern(借りたら返す)と呼ばれており、パターンの再利用のために用いられる手法
def 関数A(引数)
  # クロージャー
  def 関数B
    引数を使う処理など....
  return 関数B

クロージャ―のメリット

  • グローバル変数を減らすことができる
  • 重複する処理を減らすことができる 等

実装例

  • Webスクレイピングで使用することを想定した、要素取得用のメソッドをクロージャ―を使用して実装する
  • idで要素を取得するメソッドと、xpathで取得するメソッドそれぞれあるが、共通している内容は以下の通り
    • 各関数を実行した戻り値はいずれもhtml要素をラップしたオブジェクト
    • html要素が取得できなかった場合は例外が生じるので、例外が生じた場合はそれをcatchして処理を落とす(要素が取得できなければ、後続の処理は意味がなくなるため)
    • Convert用のクラスで整形して返す
  • closureには、各メソッドで固有の処理(find_element(By.~))のみを実装し、例外をハンドリングする用のメソッドに渡す。あとは渡されたclouserを実行するだけ
class WebBrowserOperator:
    def find_by_id(self, id_name: str) -> XWebElement:
        def closure():
            return self.webdriver.find_element(By.ID, id_name)
        return self._handle(closure)
    def find_by_xpath(self, xpath: str) -> XWebElement:
        def closure():
            return self.webdriver.find_element(By.XPATH, xpath)
        return self._handle(closure)
    def _handle(self, closure):
        try:
            web_element = closure()
            return WebElementConverter().convert([web_element]).first()

        except NoSuchElementException:
            XLogger.exceptionToSlack("対象のhtml要素が見つかりませんでした")
            XLogger.exception("対象のhtml要素が見つかりませんでした。")
            sys.exit()

Python学習におすすめの書籍

独習Python/山田祥寛【3000円以上送料無料】
bookfan 1号店 楽天市場店
¥ 3,300(2022/02/05 17:20時点)
タイトルとURLをコピーしました