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

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

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


当前回答

获取异常对象所属类的名称:

e.__class__.__name__

使用print_exc()函数也将打印堆栈跟踪,这是任何错误消息的基本信息。

是这样的:

from traceback import print_exc

class CustomException(Exception): pass

try:
    raise CustomException("hi")
except Exception as e:
    print ('type is:', e.__class__.__name__)
    print_exc()
    # print("exception happened!")

你会得到这样的输出:

type is: CustomException
Traceback (most recent call last):
  File "exc.py", line 7, in <module>
    raise CustomException("hi")
CustomException: hi

在打印和分析之后,代码可以决定不处理异常,只执行raise:

from traceback import print_exc

class CustomException(Exception): pass

def calculate():
    raise CustomException("hi")

try:
    calculate()
except CustomException as e:
    # here do some extra steps in case of CustomException
    print('custom logic doing cleanup and more')
    # then re raise same exception
    raise

输出:

custom logic doing cleanup and more

和解释器打印异常:

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    calculate()
  File "test.py", line 6, in calculate
    raise CustomException("hi")
__main__.CustomException: hi

引发后,原始异常继续向上传播调用堆栈。(注意可能的陷阱)如果你引发新的异常,它会携带新的(更短的)堆栈跟踪。

from traceback import print_exc

class CustomException(Exception):
    def __init__(self, ok):
        self.ok = ok

def calculate():
    raise CustomException(False)

try:
    calculate()
except CustomException as e:
    if not e.ok:
        # Always use `raise` to rethrow exception
        # following is usually mistake, but here we want to stress this point
        raise CustomException(e.ok)
    print("handling exception")

输出:

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    raise CustomException(e.message)
__main__.CustomException: hi    

注意traceback如何不包括第9行中的compute()函数,这是原始异常e的起源。

其他回答

下面是我处理异常的方式。我们的想法是,如果容易的话,尝试解决问题,然后在可能的情况下添加一个更理想的解决方案。不要在生成异常的代码中解决问题,否则代码会失去原始算法的跟踪,而原始算法应该被准确地编写。但是,传递解决问题所需的数据,并返回一个lambda,以防在生成它的代码之外无法解决问题。

path = 'app.p'

def load():
    if os.path.exists(path):
        try:
            with open(path, 'rb') as file:
                data = file.read()
                inst = pickle.load(data)
        except Exception as e:
            inst = solve(e, 'load app data', easy=lambda: App(), path=path)()
    else:
        inst = App()
    inst.loadWidgets()

# e.g. A solver could search for app data if desc='load app data'
def solve(e, during, easy, **kwargs):
    class_name = e.__class__.__name__
    print(class_name + ': ' + str(e))
    print('\t during: ' + during)
    return easy

目前,由于我不想考虑应用程序的用途,所以我没有添加任何复杂的解决方案。但在未来,当我了解更多可能的解决方案时(因为应用程序设计得更多),我可以添加一个以during为索引的解决方案字典。

在这个例子中,一种解决方案可能是寻找存储在其他地方的应用程序数据,比如‘app.p’文件被错误删除了。

现在,因为编写异常处理程序不是一个明智的想法(我们还不知道解决它的最佳方法,因为应用程序的设计将不断发展),我们只是返回简单的修复,这就像我们第一次运行应用程序一样(在这种情况下)。

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

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

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

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

使用下面的异常类型和异常文本

import sys
print(str(sys.exc_info()[0]).split(' ')[1].strip('>').strip("'")+"-"+(str(sys.exc_info()[1])))

如果你只想要异常类型:使用——>

import sys
print(str(sys.exc_info()[0]).split(' ')[1].strip('>').strip("'"))

由于Rajeshwar

获取异常对象所属类的名称:

e.__class__.__name__

使用print_exc()函数也将打印堆栈跟踪,这是任何错误消息的基本信息。

是这样的:

from traceback import print_exc

class CustomException(Exception): pass

try:
    raise CustomException("hi")
except Exception as e:
    print ('type is:', e.__class__.__name__)
    print_exc()
    # print("exception happened!")

你会得到这样的输出:

type is: CustomException
Traceback (most recent call last):
  File "exc.py", line 7, in <module>
    raise CustomException("hi")
CustomException: hi

在打印和分析之后,代码可以决定不处理异常,只执行raise:

from traceback import print_exc

class CustomException(Exception): pass

def calculate():
    raise CustomException("hi")

try:
    calculate()
except CustomException as e:
    # here do some extra steps in case of CustomException
    print('custom logic doing cleanup and more')
    # then re raise same exception
    raise

输出:

custom logic doing cleanup and more

和解释器打印异常:

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    calculate()
  File "test.py", line 6, in calculate
    raise CustomException("hi")
__main__.CustomException: hi

引发后,原始异常继续向上传播调用堆栈。(注意可能的陷阱)如果你引发新的异常,它会携带新的(更短的)堆栈跟踪。

from traceback import print_exc

class CustomException(Exception):
    def __init__(self, ok):
        self.ok = ok

def calculate():
    raise CustomException(False)

try:
    calculate()
except CustomException as e:
    if not e.ok:
        # Always use `raise` to rethrow exception
        # following is usually mistake, but here we want to stress this point
        raise CustomException(e.ok)
    print("handling exception")

输出:

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    raise CustomException(e.message)
__main__.CustomException: hi    

注意traceback如何不包括第9行中的compute()函数,这是原始异常e的起源。

你的问题是:“我如何才能确切地看到someFunction()中发生了什么导致异常发生?”

在我看来,您不是在问如何处理生产代码中不可预见的异常(正如许多答案所假设的那样),而是在问如何找出在开发过程中导致特定异常的原因。

最简单的方法是使用调试器,该调试器可以在未捕获异常发生的地方停止,最好不要退出,以便您可以检查变量。例如,Eclipse开源IDE中的PyDev可以做到这一点。要在Eclipse中启用该功能,请打开Debug透视图,在Run菜单中选择管理Python异常断点,并在未捕获的异常上检查挂起。