Pythonの再試行ライブラリ-粘り強さ
1.はじめに
一部のネットワークまたはその他の制御できない要因によって引き起こされる機能上の問題を回避するため。たとえば、リクエストを送信する場合、ネットワークが不安定なためにリクエストのタイムアウトの問題が発生することがよくあります。
この場合、通常、コードに再試行コードが含まれています。再試行コード自体の実装は難しくありませんが、エレガントで使いやすいコードを作成する方法は、私たちが考慮しなければならない問題です。
これがサードパーティのライブラリです-これは、次のTenacity
ように、使用できるほぼすべての再試行シナリオを実装しています。
- どのような状況で再試行しますか?
- 再試行する回数は?
- 再試行が終了するまでどのくらいかかりますか?
- 各再試行の間隔はどのくらいですか?
- 再試行失敗後のコールバック?
使用する前にインストールしてください
$ pip install tenacity
2.使用法
基本的な使い方
これを使用する簡単な方法は、再試行が必要なメソッドにデコレータを追加することです。@retry
コードが例外をスローした後、デコレータによってキャッチされて再試行されます。例外がスローされると、例外がスローされるまで再試行が続行されます。コードは正常に実行されます。
例:再試行の間隔を空けずに、実行が成功するまで無条件に再試行します
from tenacity import retry
@retry
def test_retry():
print("等待重试,重试无间隔执行...")
raise Exception
test_retry()
@wait_fixed
再試行するまでの待機時間を指定したり、@wait_random
ランダムに待機したりするために使用できます
例:成功するまで無条件に再試行しますが、2秒待ってから再試行します
from tenacity import retry, wait_fixed
@retry(wait=wait_fixed(2))
def test_retry():
print("等待重试...")
raise Exception
test_retry()
ランダムに1〜2秒待ってから、再試行してください
from tenacity import retry, wait_random
@retry(wait=wait_random(min=1, max=2))
def test_retry():
print("等待重试...")
raise Exception
test_retry()
停止の基本条件を設定する
終了条件を追加して無条件の再試行を停止し@stop_after_attempt
、再試行の最大数を設定するために使用できます
例:7回だけ再試行します
from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(7))
def test_retry():
print("等待重试...")
raise Exception
test_retry()
@stop_after_delay
再試行後の最大時間を設定するために使用できます。時間を超えると停止します。
例:再試行せずに10秒後に再試行します
from tenacity import retry, stop_after_delay
@retry(stop=stop_after_delay(10))
def test_retry():
print("等待重试...")
raise Exception
test_retry()
または、上記の2つの条件のいずれかが満たされた場合は、再試行を終了します
from tenacity import retry, stop_after_delay, stop_after_attempt
@retry(stop=(stop_after_delay(10) | stop_after_attempt(7)))
def test_retry():
print("等待重试...")
raise Exception
test_retry()
再試行するタイミングを設定する
@retry_if_exception_type
特定のエラー/例外の場合にのみ再試行するようにパラメーターを設定できます
例:再試行する前にリクエストがタイムアウトしました
from requests import exceptions
from tenacity import retry, retry_if_exception_type
@retry(retry=retry_if_exception_type(exceptions.Timeout))
def test_retry():
print("等待重试...")
raise exceptions.Timeout
test_retry()
例:再試行するIOエラー
from requests import exceptions
from tenacity import retry, retry_if_exception_type
@retry(retry=retry_if_exception_type(IOError))
def test_retry():
print("等待重试...")
raise IOError
test_retry()
カスタム条件が満たされたときに再試行します。
例:test_retry
関数
from tenacity import retry, stop_after_attempt, retry_if_result
def is_false(value):
return value is False
@retry(stop=stop_after_attempt(3),
retry=retry_if_result(is_false))
def test_retry():
return False
test_retry()
手動で再試行してください
次のように、手動でエラーをスローすることにより、TryAgain
再試行をトリガーできます。
from tenacity import retry
@retry
def do_something():
result = something_else()
if result == 23:
raise TryAgain
再試行後にエラーが再スローされました
例外が発生すると、粘り強さが再試行されます。再試行しても失敗する場合は、デフォルトでRetryError
、エラーの元の理由ではなく、上記でスローされた例外がになります。
したがって、パラメータ(reraise=True
)を追加して、再試行が失敗した場合にスローされる例外が元の例外のままになるようにすることができます。
from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(7), reraise=True)
def test_retry():
print("等待重试...")
raise Exception
test_retry()
コールバック関数を設定します
最後の再試行が失敗したときにコールバック関数を実行できます
from tenacity import *
def return_last_value(retry_state):
print("执行回调函数")
return retry_state.outcome.result() # 表示返回原函数的返回值
def is_false(value):
return value is False
@retry(stop=stop_after_attempt(3),
retry_error_callback=return_last_value,
retry=retry_if_result(is_false))
def test_retry():
print("等待重试中...")
return False
print(test_retry())
出力は次のとおりです。
等待重试中...
等待重试中...
等待重试中...
执行回调函数
False