Some_function()在执行时引发异常,因此程序跳转到异常:

try:
    some_function()
except:
    print("exception happened!")

如何查看导致异常发生的原因?


当前回答

使用类型class和as语句

try:#code
except Exception as e:
     m=type(e)
     #m is the class of the exception
     strm=str(m)
     #strm is the string of m

其他回答

其他答案都指出不应该捕获通用异常,但似乎没有人愿意告诉您原因,这对于理解何时可以打破“规则”至关重要。下面是一个解释。基本上,这样你就不会隐藏:

发生错误的事实 发生错误的细节(错误隐藏反模式)

因此,只要您注意不做这些事情,就可以捕获泛型异常。例如,你可以用另一种方式向用户提供异常信息,比如:

在GUI中以对话框的形式显示异常 将异常从工作线程或进程转移到多线程或多处理应用程序中的控制线程或进程

那么如何捕捉泛型异常呢?有几种方法。如果你只想要一个异常对象,可以这样做:

try:
    someFunction()
except Exception as ex:
    template = "An exception of type {0} occurred. Arguments:\n{1!r}"
    message = template.format(type(ex).__name__, ex.args)
    print message

Make sure message is brought to the attention of the user in a hard-to-miss way! Printing it, as shown above, may not be enough if the message is buried in lots of other messages. Failing to get the users attention is tantamount to swallowing all exceptions, and if there's one impression you should have come away with after reading the answers on this page, it's that this is not a good thing. Ending the except block with a raise statement will remedy the problem by transparently reraising the exception that was caught.

上述用法和使用just except: without any argument的区别有两个方面:

裸except:不提供要检查的异常对象 异常SystemExit, KeyboardInterrupt和GeneratorExit不会被上面的代码捕获,这通常是你想要的。参见异常层次结构。

如果你也想要与你没有捕获异常时得到的stacktrace相同,你可以像这样得到(仍然在except子句中):

import traceback
print traceback.format_exc()

如果你使用logging模块,你可以像这样将异常输出到日志中(以及一条消息):

import logging
log = logging.getLogger()
log.exception("Message for you, sir!")

如果你想更深入地研究堆栈,查看变量等,可以使用except块内pdb模块的post_mortem函数:

import pdb
pdb.post_mortem()

我发现最后一种方法在查找bug时非常有用。

使用类型class和as语句

try:#code
except Exception as e:
     m=type(e)
     #m is the class of the exception
     strm=str(m)
     #strm is the string of m

除非某个函数是一个编码非常糟糕的遗留函数,否则你不应该需要你所要求的。

使用多个except子句以不同的方式处理不同的异常:

try:
    someFunction()
except ValueError:
    # do something
except ZeroDivision:
    # do something else

重点是不应该捕获通用异常,而应该只捕获需要捕获的异常。我相信您不希望看到意外的错误或bug。

为了补充Lauritz的答案,我创建了一个用于异常处理的装饰器/包装器,并且包装器记录发生了哪种类型的异常。

class general_function_handler(object):
    def __init__(self, func):
        self.func = func
    def __get__(self, obj, type=None):
        return self.__class__(self.func.__get__(obj, type))
    def __call__(self, *args, **kwargs):
        try:
            retval = self.func(*args, **kwargs)
        except Exception, e :
            logging.warning('Exception in %s' % self.func)
            template = "An exception of type {0} occured. Arguments:\n{1!r}"
            message = template.format(type(e).__name__, e.args)
            logging.exception(message)
            sys.exit(1) # exit on all exceptions for now
        return retval

这可以在类方法或带有装饰器的独立函数上调用:

@general_function_handler

完整的例子请参阅我的博客:http://ryaneirwin.wordpress.com/2014/05/31/python-decorators-and-exception-handling/

在Python 2中,以下代码很有用

except Exception, exc:

    # This is how you get the type
    excType = exc.__class__.__name__

    # Here we are printing out information about the Exception
    print 'exception type', excType
    print 'exception msg', str(exc)

    # It's easy to reraise an exception with more information added to it
    msg = 'there was a problem with someFunction'
    raise Exception(msg + 'because of %s: %s' % (excType, exc))