Python的重试装饰器

时间:2015-07-30 15:42:13

标签: python dynamic python-decorators

我目前正在使用包含@retry装饰器的python retrying package,其中包含许多可选参数。我已经为我们的生产环境正确设置了这些参数,并且在重试之间有足够长的等待时间(低于它设置为2000毫秒)但是我想为单元测试目的设置不同的这些值,以便执行非常快。

例如,wait_fixed时间设置为2000毫秒用于生产,但我的单元测试调用some_function()我想将wait_fixed参数覆盖为1毫秒,因此执行速度非常快

@retry(stop_max_attempt_number=3, wait_fixed=2000)
def some_function(self):
    return True

我遇到的问题是装饰器是interpreted when the function is defined,所以我还没有找到一种方法来覆盖单元测试中的wait_fixed参数。

3 个答案:

答案 0 :(得分:2)

main.py

import settings
from retrying import retry


@retry(stop_max_attempt_number=settings.STOP_MAX_ATTEMPT_NUMBER, 
       wait_fixed=settings.WAIT_FIXED)
def some_function(self):
    return True

settings.py

import json


with open('config.json') as jsonf:
    config = json.loads(jsonf.read())

WAIT_FIXED=int(config['WAIT_FIXED'])
STOP_MAX_ATTEMPT_NUMBER=int(config['STOP_MAX_ATTEMPT_NUMBER'])

config.json

{
    "STOP_MAX_ATTEMPT_NUMBER" : "3",
    "WAIT_FIXED" : "2000"
}

让你的测试跑步者选择合适的config.json

答案 1 :(得分:1)

我需要能够在调用函数时动态设置重试参数,下面对我来说效果很好:

import random
from retrying import retry


class MyClass(object):

    def try_stuff(self, string, attempts, wait):
        self.do_something_with_retry = retry(stop_max_attempt_number=attempts,
                                             wait_fixed=wait)(self.do_something_unreliable)
        return self.do_something_with_retry(string)

    def do_something_unreliable(self, string):
        print(string)
        if random.randint(0, 10) > 1:
            raise IOError("Broken sauce, everything is hosed!!!111one")
        else:
            return "Awesome sauce!"

instance = MyClass()

print instance.try_stuff('test', 10, 2000)

答案 2 :(得分:1)

我最近遇到一个问题,defdef解决了这个问题。

我需要在get_url函数上使用重试装饰器,但需要传递stop_max_attempt_number的可配置值。我无法在同一缩进处找到get_url以及其他函数。

要解决此问题,我在 get_url函数中定义了get_analytic函数。例如:

def get_analytics(conf: Configuration, assets: list, cache: dict) -> list:
    STOP_MAX_ATTEMPT_NUMBER = int(conf.num_retry)
    WAIT_FIXED = int(conf.retry_timeout)
    @retry(stop_max_attempt_number=STOP_MAX_ATTEMPT_NUMBER, wait_fixed=WAIT_FIXED)
    def get_url(disable_https: bool, url: str, user: str, password: str) -> Response: