cle*_*oux 11 python exception-handling
在python中处理异常时,我发现自己经常重复代码.基本模式是这样的形式:
try:
action_here()
except CommonException1:
Action_always_taken_for_CommonException1()
except CommonException2:
Action_always_taken_for_CommonException2()
except Exception:
Default_action_always_taken()
Run Code Online (Sandbox Code Playgroud)
我想要做的是将一些重复代码抽象出一个函数或类.我知道一种方法是使用异常对象调用异常处理函数,例如:
try:
action_here()
except Exception as e:
handle_exception(e)
Run Code Online (Sandbox Code Playgroud)
然后在此函数中根据类确定异常.
def handle_exception(e):
if type(e) == type(CommonException1()):
Action_always_taken_for_CommonException1()
elif type(e) == type(CommonException2()):
Action_always_taken_for_CommonException2())
else:
Default_action_always_taken()
Run Code Online (Sandbox Code Playgroud)
然而,这感觉笨重而且不优雅.所以我的问题是,处理重复异常处理还有哪些其他选择?
nco*_*lan 19
这种情况是上下文管理器和with语句的主要用例之一:
from __future__ import with_statement # Needed in 2.5, but not in 2.6 or later
from contextlib import contextmanager
@contextmanager
def handle_exceptions():
try:
yield # Body of the with statement effectively runs here
except CommonException1:
Action_always_taken_for_CommonException1()
except CommonException2:
Action_always_taken_for_CommonException2()
except Exception:
Default_action_always_taken()
# Used as follows
with handle_exceptions():
action_here()
Run Code Online (Sandbox Code Playgroud)
如果您不喜欢重复if/ elseif块,您可以将句柄放在一个dict中,键入类型:
handlers = { type(CommonException1()) : Action_always_taken_forCommonException1,
type(CommonException2()) : Action_always_taken_forCommonException2 }
def handle_exception(te):
if te in handlers:
handlers[te]()
else:
Default_action()
Run Code Online (Sandbox Code Playgroud)
然后你可以运行:
try:
action_here()
except Exception as e:
handle_exception(type(e))
Run Code Online (Sandbox Code Playgroud)
另外:如果您发现自己经常编写这些try块,那么您可以编写自己的上下文管理器(请参阅此处).在action_here()旁边,您的代码将如下所示:
with my_error_handling_context():
action_here1()
action_here2()
Run Code Online (Sandbox Code Playgroud)
在这种情况下,handle_exception代码本质上是您的上下文管理器的__exit__方法(它总是会传递在with块期间引发的任何异常).
虽然使用上下文管理器的解决方案(由其他人提出)是最优雅的,也是我推荐的解决方案,但我想指出handle_exception通过重新引发异常可以更优雅地编写函数:
def handle_exception(e):
try:
raise e
except CommonException1:
Action_always_taken_for_CommonException1()
except CommonException2:
Action_always_taken_for_CommonException2()
except Exception:
Default_action_always_taken()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1730 次 |
| 最近记录: |