python-reraise重新抛出自定义异常——如何使traceback选择性保留?

1. 自定义异常

 在python中,自定义一个异常类的方法如下:

新建一个python文件exception.py,以后可以将该工程内的所有自定义异常类都写到该文件下。代码如下:

"""
自定义异常类
"""


# 参数类型异常类
class ParameterTypeError(Exception):
    _error_code = -1
    _error_type = "TypeError"

    def __init__(self, error_msg=""):    #可以理解为java的构造函数
        super().__init__(self)  # 初始化父类
        self.error_msg = error_msg    #设置构造函数的工作

    def __str__(self):    #设置转化为string的格式
        return '错误类型:' + ParameterTypeError._error_type + ';错误提示:' + self.error_msg


if __name__ == '__main__':
    try:
        raise ParameterValueError('参数异常')
    except ParameterValueError as e:
        print(e)

2. 如何重新抛出自定义异常?

如下代码,inner()方法会raise一个ConnectionError,在outer()方法中捕获该异常,然后抛出自定义的异常

def outer():
    try:
        inner()
    except Connection as e:
        raise ParameterValueError

3.traceback异常栈

如2代码 ,在python2及java的逻辑中,traceback会丢失捕捉的connectionError的异常信息,只保留未捕捉的异常:

但在python3中,会默认附加上捕捉的上个异常的traceback信息,如图: 

要想忽略掉被捕捉的异常,需要在抛出最后一个异常使用:

raise ParameterValueError from None

4.Traceback常用方法

在except代码块中,使用以下方法,可以捕捉traceback相应信息:

1. 

print('发生错误的文件:', e.__traceback__.tb_frame.f_globals['__file__'])

print('错误所在的行号:', e.__traceback__.tb_lineno)

print('错误信息', e)

2.(需要import sys)

sys.exc_info() 会返回一个3值元表 (type, value, traceback) ,其中:

  • type 从获取到的异常中得到类型名称,它是BaseException 的子类;
  • value 是捕获到的异常实例;
  • traceback 是一个 traceback 对象。

3.(需要import traceback)

traceback.extract_tb(tb [,limit ] )返回一个堆栈中异常信息(FrameSummary对象)列表,每一个对象是一个四元组(文件名,行号,函数名称*,文本), limit为条数

示例代码:

if __name__ == '__main__':
    try:
        main()
    except ConnectionError as e:
        t, v, tb = sys.exc_info()
        print(traceback.extract_tb(tb, 2))
    raise ParameterValueError from None

输出:

[<FrameSummary file /Users/mengxiangfen/project/tutor-ybc-course-pypackage/ybc_history/ybc_history/ybc_history.py, line 97 in <module>>, 
<FrameSummary file /Users/mengxiangfen/project/tutor-ybc-course-pypackage/ybc_history/ybc_history/ybc_history.py, line 91 in main>]

通过FrameSummary.filename, FrameSummary.lineno, FrameSummary.name可以获取到文件名/行号 /函数名

5. 如何在Python2中保留之前的异常栈信息?

https://mozillazg.com/2016/08/python-the-right-way-to-catch-exception-then-reraise-another-exception.html#hidpython-2

猜你喜欢

转载自blog.csdn.net/NNnora/article/details/84137036