Pythonで関数のリトライ処理を実行したくなったので,retry 1 というライブラリを使い方を調べながら使った. 簡単に書けるし,リトライの制御をexceptionで出来るしめちゃくちゃ好みのライブラリだった.

簡単な使い方

自分が知りたかったのをまとめる

成功するまでリトライする


import random

from retry import retry

@retry()
def retry_func():
    if random.random() > 0.5:
        retrun
    else:
        raise Exception


if __name__ = "__main__":
    retry_func()

特定の例外のみリトライする


import random

from retry import retry

class ExceptionA(Exception):
    pass

class ExceptionB(Exception):
    pass


@retry(exceptions=(ExceptionA))
def retry_func():
    if random.random() > 0.5:
        raise ExceptionA
    elif random.random() > 0.3:
        raise ExceptionA
    else:
        retrun


if __name__ = "__main__":
    retry_func()

ExceptionA が来た時だけリトライする. exceptions はタプルを引数にとるので,複数の例外でリトライしたい時にはタプルに入れていこう.

特定の回数までリトライスル


import random

from retry import retry

class ExceptionA(Exception):
    pass

class ExceptionB(Exception):
    pass


@retry(exceptions=(ExceptionA), tries=3)
def retry_func():
    if random.random() > 0.5:
        raise ExceptionA
    elif random.random() > 0.3:
        raise ExceptionA
    else:
        retrun


if __name__ = "__main__":
    retry_func()

これで3回までリトライしてくれる. また、 tries0 を入れると1回も実行してくれないので注意。

リトライするのにちょっと待つ


import random

from retry import retry

class ExceptionA(Exception):
    pass

class ExceptionB(Exception):
    pass


@retry(exceptions=(ExceptionA), tries=3, delay=1)
def retry_func():
    if random.random() > 0.5:
        raise ExceptionA
    elif random.random() > 0.3:
        raise ExceptionA
    else:
        retrun


if __name__ = "__main__":
    retry_func()

delay を使えば再試行をまってくれる. 単位は秒

ディレイとかを引数で決めたい.


import random

from retry import retry

class ExceptionA(Exception):
    pass

class ExceptionB(Exception):
    pass


def retry_func(retry_num, delay_time):

    @retry(exceptions=(ExceptionA), tries=retry_num, delay=delay_time)
    def retry_func():
        if random.random() > 0.5:
            raise ExceptionA
        elif random.random() > 0.3:
            raise ExceptionA
        else:
            retrun

    return retry_func()


if __name__ = "__main__":
    retry_func()

関数の中で関数作れば良いよ,

デコレータじゃなくて, retry_call という関数を使う方法もある.

import random

from retry.api import retry_call

class ExceptionA(Exception):
    pass

class ExceptionB(Exception):
    pass


def retry_func(retry_num, delay_time):
    def retry_func():
        if random.random() > 0.5:
            raise ExceptionA
        elif random.random() > 0.3:
            raise ExceptionA
        else:
            retrun

    return retry_call(retry_func, fargs=[], fkwargs={}, exceptions=(ExceptionA), tries=retry_num, delay=delay_time)


if __name__ = "__main__":
    retry_func()

こっちは,適当な関数をリトライする関数に出来るのでライブラリとか使う時に便利そう.