リトライ処理をデコレーターにまとめたかったので作りました
デコレーターとは?
度々、Python のメソッドの前に付いている @xxx
の部分のことです。
ChatGPT に「そもそもデコレーターとは?」を聞いてみました
質問
Python におけるデコレーターってなんですか?
ChatGPT の回答
デコレーターは、Python の関数やメソッド、クラスに です。簡単に言えば、「ある関数やクラスを他の関数でラップして、動作を拡張する仕組み」です。
メソッドをラップできる機能ということですね。今回は特定のメソッドをラップしてリトライ機能を追加するという感じですね
デコレーター
[retry_decorator.py] import functools import time def retry_on_exception(*, max_attempts: int = 1): """Retry decorator.""" def decorator(func: callable): @functools.wraps(func) def wrapper(*args, **kwargs): for attempt in range(max_attempts): try: print(f'Calling (Attempt: {attempt + 1})') return func(*args, **kwargs) except Exception as ex: last_exception = ex print(f'Failed on (Attempt: {attempt + 1})') if attempt < max_attempts - 1: delay = 2 ** attempt time.sleep(delay) continue raise last_exception return wrapper return decorator
リトライ処理のアプローチは エクスポネンシャルバックオフ です
実行コード
[run.py] from retry_decorator import retry_on_exception @retry_on_exception(max_attempts=3) def unstable_function(): """意図的に例外を発生させる関数。""" raise ValueError("Intentional error for testing.") @retry_on_exception(max_attempts=3) def stable_function(): """一度で成功する関数。""" return "Success" if __name__ == '__main__': print("===== stable_function() =====") res = stable_function() assert res == 'Success' print("===== unstable_function() =====") try: unstable_function() except ValueError as ex: print(ex)
実行ログ
$ python run.py ===== stable_function() ===== Calling (Attempt: 1) ===== unstable_function() ===== Calling (Attempt: 1) Failed on (Attempt: 1) Calling (Attempt: 2) Failed on (Attempt: 2) Calling (Attempt: 3) Failed on (Attempt: 3) Intentional error for testing.
まとめ
なんかいい感じに動いたので嬉しい。毎回、各メソッドにリトライ処理書いてたのでこれから楽できる・・・。それよりも久々に VSCode で Python ファイルを開いたんだけど、全く推論や補完してくれなくなってる・・・