環境
- Windows 10
- Python 3.10.1
- VSCode
クロージャ―とは
- 関数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でクロージャーを実装する方法について紹介しています。ぜひ参考にしてみてください。