如果我像这样创建一个python装饰器函数
def retry_until_true(tries, delay=60):
"""
Decorator to rety a function or method until it returns True.
"""
def deco_retry(f):
def f_retry(*args, **kwargs):
mtries = tries
rv = f(*args, **kwargs)
while mtries > 0:
if rv is True:
return True
mtries -= 1
time.sleep(delay)
rv = f(*args, **kwargs)
return False
return f_retry
return deco_retry
我可以像这样使用它
@retry_until_true(20, delay=30)
def check_something_function(x, y):
...
return True
但有没有办法在运行时将'尝试'和'延迟'的不同值传递给装饰器,以便20和30是变量?
答案 0 :(得分:5)
您可以使用类作为装饰器,使用tries
和delay
的实例变量:
class RetryUntilTrue(object):
def __init__(self, f=None, tries=10, delay=30):
self.f = f
self.tries = tries
self.delay = delay
def __call__(self, *args, **kwargs):
if self.f is None:
self.f = args[0]
else:
tries = self.tries
while tries:
if self.f(*args, **kwargs):
return True
tries -= 1
time.sleep(self.delay)
用法:
@RetryUntilTrue
def foo(x):
pass
foo.tries = 20
foo.delay = 1
@RetryUntilTrue(tries=100, delay=9999)
def bar(x):
pass
bar.tries -= 1
bar.delay = foo.delay
答案 1 :(得分:2)
当然可以,只需将函数定义嵌套在另一个函数中,例如:
def explicit_setup_func(tries, delay=60):
@retry_until_true(tries, delay)
def check_something_function(x, y):
# Code
然而,类装饰器解决方案更实用。