[英]Repeat Python function call on exception?
Hey everybody I'm working on a data scraping project and I'm looking for a clean way to repeat a function call if an exception is raised. 嘿大家我正在研究数据抓取项目,如果引发异常,我正在寻找一种简洁的方法来重复函数调用。
Pseudo-code: 伪代码:
try:
myfunc(x)
except myError:
###try to call myfunc(x) again Y number of times,
until success(no exceptions raised) otherwise raise myError2
I realize this isn't best practice at all but I'm working through a number of different code/network layers that aren't reliable and I can't realistically debug them. 我意识到这根本不是最佳实践,但我正在研究一些不可靠的不同代码/网络层,我无法实际调试它们。
Right now I'm accomplishing this with a huge set of try\\except blocks and it's making my eyes bleed. 现在我正在通过一系列尝试来完成这个尝试\\除了块,它让我的眼睛流血。
Elegant ideas anyone? 优雅的想法谁?
To do precisely what you want, you could do something like the following: 要做到你想要的,你可以做如下的事情:
import functools
def try_x_times(x, exceptions_to_catch, exception_to_raise, fn):
@functools.wraps(fn) #keeps name and docstring of old function
def new_fn(*args, **kwargs):
for i in xrange(x):
try:
return fn(*args, **kwargs)
except exceptions_to_catch:
pass
raise exception_to_raise
return new_fn
Then you just wrap the old function in this new function: 然后你只需将旧函数包装在这个新函数中:
#instead of
#risky_method(1,2,'x')
not_so_risky_method = try_x_times(3, (MyError,), myError2, risky_method)
not_so_risky_method(1,2,'x')
#or just
try_x_times(3, (MyError,), myError2, risky_method)(1,2,'x')
Use a loop 使用循环
i = 0
while True:
try: myfunc(x); break;
except myError:
i = i + 1;
# print "Trying again"
if i > 5: raise myError2;
for x in xrange(num_retries):
try:
myFunc()
except MyError, err:
continue
#time.sleep(1)
err = None
break
if err:
raise MyError2
#else:
# print "Success!"
To raise Exception as usual after n retries 在重试之后像往常一样提高异常
from functools import wraps
def retry(times):
"""
Decorator to retry any functions 'times' times.
"""
def retry_decorator(func):
@wraps(func)
def retried_function(*args, **kwargs):
for i in range(times - 1):
try:
func(*args, **kwargs)
return
except Exception:
pass
func(*args, **kwargs)
return retried_function
return retry_decorator
# test
attempts = 3
@retry(4)
def function_that_raises_error():
global attempts
if 0 < attempts:
print("fail")
attempts -= 1
raise Exception
print("pass")
function_that_raises_error()
I like to do these problems with recursion: 我喜欢用递归来做这些问题:
def tryfor(times, on_failure, excepts, func, *args, **kwargs):
if times < 1:
raise on_failure()
try:
return func(*args, **kwargs)
except excepts:
return tryfor(times-1, on_failure, excepts, func, *args, **kwargs)
tryfor(3, PermanentException, (SomeError,), dostuff,1,2)
Try following snippet: 请尝试以下代码段:
while True:
try:
func()
break
except:
print "Error. Gonna try again"
But it is better to limit the number of retries. 但最好限制重试次数。
success = False
attempts = 0
while not success and attempts < 10: # or however many times you want to attempt
try:
functionCall()
success = True
except:
i += 1
if not success:
raise functionCallFailedError
Hope this helps 希望这可以帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.