我有一个异常实例,需要根据它的类型执行代码。哪种方式更清楚 - 重新提出异常或实例检查?
再加注:
try:
raise exception
except OperationError as err:
result = do_something1(err)
except (InvalidValue, InvalidContext) as err:
result = do_something2(err)
except AnotherException as err:
result = do_something3(err)
except:
pass
isinstance check:
if isinstance(exception, OperationError):
result = do_something1(err)
elif isinstance(exception, (InvalidValue, InvalidContext)):
result = do_something2(err)
elif isinstance(exception, AnotherException):
result = do_something3(err)
PS。代码在django process_exception中间件中使用,因此当重新引发异常时,我应该为所有未知异常写except:pass
。
答案 0 :(得分:1)
您可以将要处理的异常作为键存储在具有不同功能的字典中作为其值。然后,您可以只在一个return (chars.size() == alphabet.size());
中捕获所有错误,并调用字典以确保运行相关功能。
except
我怀疑可能有一种方法可以通过编程方式将error_handler = {
OperationError: do_something1,
InvalidValue: do_something2,
InvalidContext: do_something2,
AnotherException: do_something3,
}
try:
#raise your exception
except (OperationError, InvalidValue, InvalidContext, AnotherException) as err:
result = error_handler[type(err)]()
传递给error_handler.keys()
,但我在Python2.7中尝试过的方法到目前为止还没有用过。
请注意,正如martineau指出的那样,因为它使用except
作为字典键,所以它不会像type(err)
和isinstance(err, ...)
那样处理派生的异常类。您需要匹配确切的例外。
答案 1 :(得分:1)
首先摆脱except: pass
子句 - 一个人应该永远默默地传递异常,特别是在一个裸except
子句中(一个人永远不应该使用except
无论如何)。
话虽如此,“最佳”方式实际上取决于具体的用例。在上面的示例中,您明确地为不同的异常/异常集设置了不同的处理程序,因此显而易见的解决方案是第一个。有时您确实拥有一些对所有或大多数处理程序通用的代码以及一些特定于一个异常或异常子集的代码,那么您可能希望对特定部分使用isinstance
,即:
try:
something_that_may_fail()
except (SomeException, SomeOtherException, YetAnotherOne) as e:
do_something_anyway(e)
if isinstance(e, YetAnotherOne):
do_something_specific_to(e)
现在正如mkrieger评论的那样,有三个或更多例外来处理可能是一个代码或设计气味 - try块中的部分可能做了太多事情 - 但有时候你有时候也会这样做有很多选择(调用内置函数或第三部分函数,可以通过多种方式失败......)。