Python - 有条理地捕获异常

spe*_*ane 16 python exception-handling exception

是否有可能有条件地捕获python中的异常?我希望能够编写一个函数,以便调用者可以决定谁处理异常.

基本上,我想要这样的事情:

def my_func(my_arg, handle_exceptions):
    try:
        do_something(my_arg)
    except Exception, e if handle_exceptions:
        print "my_func is handling the exception"
Run Code Online (Sandbox Code Playgroud)

我知道我可以写一些符合我想要的kludgy代码,但如果有的话,我想要一个pythonic答案.
谢谢.

cho*_*own 23

如果您不想处理异常,可以重新引发异常:

def my_func(my_arg, handle_exceptions):
    try:
        do_something(my_arg)
    except Exception, e:
        if not handle_exceptions:
            # preserve prior stack trace
            raise

            # Or, if you dont care about the stack prior to this point
            #raise Exception(e)

            # similarly, you can just re-raise e.  The stack trace will start here though.
            #raise e
        else:
            print "my_func is handling the exception"
Run Code Online (Sandbox Code Playgroud)

另一个选择是创建自己的子类Exception(或类似的特定异常urllib2.HTTPError),然后只捕获/ throw(raise)自定义异常:

class MyException(Exception):
    def __init__(self, message):
        self.message = message

class MyExceptionTwo(Exception):
    def __init__(self, message):
        self.message = message
    def __repr__(self):
        return "Hi, I'm MyExceptionTwo.  My error message is: %s" % self.message

def something():
    if not tuesday:
        raise MyException("Error: it's not Tuesday.")
    else:
        raise MyExceptionTwo("Error: it's Tuesday.")

def my_func(my_arg):
    try:
        something()
    except MyException, e:
        print e.message
    # Will pass MyExceptionTwo up the call chain

def my_other_func():
    try:
        my_func(your_arg)
    except MyExceptionTwo, e:
        print str(e)
    # No need to catch MyException here since we know my_func() handles it
    # but we can hadle MyExceptionTwo here
Run Code Online (Sandbox Code Playgroud)

  • @speedplane如果你只是使用`raise`,那么堆栈将保持不变.如果你"提高e"或"提高异常(e)",它将在你引发它的位置开始堆栈跟踪. (4认同)

Ray*_*ger 14

这个问题没有足够的答案;-)

这是记录簿的另外一个.只需创建一个虚拟异常:

class NeverMatch(Exception):
    'An exception class that is never raised by any code anywhere'
Run Code Online (Sandbox Code Playgroud)

然后,使用条件表达式来决定是匹配实际异常还是占位符异常(永远不会被引发):

try:
    do_something(my_arg)
except (Exception if handle_exceptions else NeverMatch) as e:
    print 'I am handling it'
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常好的解决方案!谢谢Hettinger先生:) (2认同)

mil*_*ose 5

您可以使用:

def my_func(my_arg, handle_exceptions):
  try:
    do_something(my_arg);
  except Exception as e:
    if not handle_exceptions: raise
    print "my_func is handling the exception";
Run Code Online (Sandbox Code Playgroud)


mor*_*tar 5

异常类型可以是变量.

def my_func(my_arg, handle_exceptions):
  if handle_exceptions:
    exc_type = Exception
  else:
    exc_type = None

  try:
    do_something(my_arg);
  except exc_type, e:
    print "my_func is handling the exception";
Run Code Online (Sandbox Code Playgroud)

混淆的Python("Pythonic"?)版本:

def my_func(my_arg, handle_exceptions):
  try:
    do_something(my_arg);
  except (handle_exceptions and Exception), e:
    print "my_func is handling the exception";
Run Code Online (Sandbox Code Playgroud)

实际上,在没有括号的情况下工作,但只要我们被混淆,就不要混淆人们那些鲜为人知的规则,比如除了语句之外的优先级.

  • `除了None'在Python 3.x中不起作用 (3认同)