比方说,我有三个函数可做不同的事情,但应以相同的方式对一组异常做出反应。其中之一可能看起来像:
def get_order_stat(self, Order_id):
status_returned = False
error_count = 0
while status_returned == False:
try:
stat_get = client.queryOrder(orderId=Order_id)
except MalformedRequest:
print('Order ID not yet findable, keep trying')
error_count += 1
time.sleep(int(1))
except InternalError:
print('Order check returned InternalError, keep trying')
error_count += 1
time.sleep(int(1))
except StatusUnknown:
print('Order check returned StatusUnknown, keep trying')
error_count += 1
time.sleep(int(1))
else:
status = stat_get['status']
status_returned = True
finally:
if error_count >= 10:
print('Error loop, give up')
break
return status
绝大多数代码是异常处理,我想避免在每个需要它的函数中重复它。有没有一种方法可以定义类似包含处理代码的异常处理函数?理想情况下,我的功能可以有效地结束:
def get_order_stat(self, Order_id):
status_returned = False
while status_returned == False:
try:
stat_get = client.queryOrder(orderId=Order_id)
except:
handler_function()
else:
status = stat_get['status']
status_returned = True
return status
答案 0 :(得分:1)
您实际上已经做到了。只需在某个地方定义handler_function(),并在try块中引发Exception时调用它。
也许有用:您可以将Exception绑定到变量,并在处理程序函数中将其用于异常处理:
except Exception as e:
handler_function(e)
然后,您可以例如执行`print(e)̀以发出异常,或对函数中的不同异常进行不同的处理。希望有帮助!
如果您不想变得笼统,也可以在一行中指定几个例外,但是用一条语句捕获所有特定例外:
except (ExceptionType1, ExceptionType2, ExceptionType3) as e:
handler_function(e)
答案 1 :(得分:1)
我可能会编写一个装饰器函数来处理异常;例如使用functool.wraps。
from functool import wraps
def retry(f):
@wraps(f)
def wrapper(*args, **kwargs):
error_count = 0
while error_count < 10:
try:
return f(*args, **kwargs)
except MalformedRequest:
print('Order ID not yet findable, keep trying')
except InternalError:
print('Order check returned InternalError, keep trying')
error_count += 1
time.sleep(int(1))
print('Error loop, give up')
return None
return wrapper
然后,您可以编写一个非常简单的API调用函数,并使用重试包装器将其包装:
@retry
def get_order(order_id):
stat_get = client.queryOrder(orderId=order_id)
return stat_get['status']
在原始功能中,请注意,您可以将try
... else
块的内容移动到主try
块中,而不会影响逻辑(从查询结果不会引发与网络相关的异常之一),然后您可以返回try
块,而不必安排停止循环。然后,我在这里将try
块的内容分解为get_order()
。我对剩余的循环进行了一些重组,然后将其转换为装饰器形式。