在python中,有哪些优雅的方法可以抽象出重复的异常处理?

在python中,有哪些优雅的方法可以抽象出重复的异常处理?,python,exception-handling,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() 我

在python中处理异常时,我发现自己经常重复代码。基本模式的形式如下:

try:
  action_here()
except CommonException1:
  Action_always_taken_for_CommonException1()
except CommonException2:
  Action_always_taken_for_CommonException2()
except Exception:
  Default_action_always_taken()
我想做的是了解如何将这些重复代码抽象成函数或类。我知道一种方法是使用exception对象调用异常处理函数,例如:

try:
  action_here()
except Exception as e:
  handle_exception(e)
然后在此函数中根据类确定异常

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()

然而,这让人感觉笨拙和不雅。因此,我的问题是,除了处理重复的异常处理,还有什么其他替代方法?

如果您不喜欢重复的
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()
然后您可以使用它运行:

try:
  action_here()
except Exception as e:
  handle_exception(type(e))

此外:如果您发现自己经常编写这些try块,那么您可以编写自己的上下文管理器(请参阅)。在
action\u here()
一侧,您的代码将如下所示:

with my_error_handling_context():
  action_here1()
  action_here2()

在这种情况下,
handle\u exception
代码本质上是您的上下文管理器的
\uuuuuuuuuuuuuuuu退出
方法(它将始终通过with块期间引发的任何异常)

这种情况是上下文管理器和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()

虽然使用上下文管理器(如其他人所建议)的解决方案是最优雅的,也是我的建议,但我想指出,通过重新引发异常,可以更优雅地编写
handle\u 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()

这看起来很优雅。你想用什么?@Blender我的解决方案是我想出的唯一可行的解决方案。我想知道是否有人知道更好的解决方案。这正是我想要的类型。谢谢上下文管理器正是我想要的解决方案类型。谢谢谢谢,我自己从来没有想到过。