ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

traceback:让你更加灵活地处理python的异常

2019-06-30 21:43:38  阅读:260  来源: 互联网

标签:py exc 灵活 python traceback Desktop print wtfpython


异常

异常在python中是屡见不鲜了,程序在执行到某一行代码时,发现有问题,比如数组索引越界,变量没有定义啊等等,此时就会抛出异常

捕获异常

在python,一般都是使用try···except来对异常进行捕获

try:
    1 / 0
except Exception as e:
    print(e)  # division by zero

然而仅仅只有这些也看不出什么东西来,我们需要知道在哪一行代码引发的异常。

大家在程序报错的时候,会经常看到报错信息如下

Traceback (most recent call last):

这个Traceback是什么鬼?实际上,这是python关于程序报错的回溯信息,来自于一个叫做traceback object的对象,而这个traceback object对象是通过sys.exc_info()来获取的


traceback对象

import sys


try:
    1 / 0
except Exception as e:
    print(e)  # division by zero
    exc_type, exc_value, exc_tb = sys.exc_info()
    print(exc_type)  # <class 'ZeroDivisionError'>
    print(exc_value)  # division by zero
    print(exc_tb)  # <traceback object at 0x0000000009F484C8>

可以看到,sys.exc_info()获取了当前处理的exception的相关信息,并返回一个元组。元组的第一个元素是异常的类型,第二个元素是异常的value值,第三个异常信息则是traceback object。print(e)打印的是异常的值。

有了traceback object我们则可以打印和格式化traceback的相关信息


traceback模块


接收一个tracebackobject

import sys
import traceback


try:
    1 / 0
except NameError as e:
    exc_type, exc_value, exc_tb = sys.exc_info()
    traceback.print_tb(exc_tb)
"""
File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in <module>
    1 / 0
"""

# 如果我们不捕获异常看看输出啥?
"""
Traceback (most recent call last):
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in <module>
    1 / 0
ZeroDivisionError: division by zero
"""
# 可以看到最后一行的ZeroDivisionError则是异常类型,division by zero则是异常值。中间的则是我们的traceback object

然而除了traceback object,print_tb还可以接收两个参数

  • limit

    比如我们在调用C函数出现了异常,但我们是先调用A函数,在A函数里面调用B函数,在B函数里面调用C函数,limit参数则是限制stack trace的层级的,如果为None也就是不指定,那么会打印所有层级

    import sys
    import traceback
    
    
    def C():
        1 / 0
    
    def B():
        C()
    
    def A():
        B()
    
    
    try:
        A()
    except Exception as e:
        exc_type, exc_value, exc_tb = sys.exc_info()
        traceback.print_tb(exc_tb)
        """
          File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module>
            A()
          File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A
            B()
          File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 9, in B
            C()
          File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in C
            1 / 0
        """
    
        traceback.print_tb(exc_tb, limit=2)
        """
          File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module>
            A()
          File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A
            B()
        """
  • file

    可以指定file,输出到某个文件里,默认是sys.stderr


与print_tb相比多了两个参数,需要传入exc_type,exc_value,exc_tb,也就是sys.exc_info返回的三个值。与print_tb相比,打印信息多了开头的Traceback (most recent call last):,以及最后一行的异常类型和value信息。还有一个不同是当异常为SyntaxError时,会有"^"来指示语法错误的位置

import sys
import traceback


def C():
    1 / 0

def B():
    C()

def A():
    B()


try:
    A()
except Exception as e:
    exc_type, exc_value, exc_tb = sys.exc_info()
    traceback.print_exception(exc_type, exc_value, exc_tb)
"""
Traceback (most recent call last):
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module>
    A()
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A
    B()
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 9, in B
    C()
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in C
    1 / 0
ZeroDivisionError: division by zero
"""

可以看到,打印的结果和报错的信息是一样的。


和print_exception类似,只不过不需要我们手动的传入sys.exc_info返回的三个值,而是会自动帮我们调用

import sys
import traceback


def C():
    1 / 0

def B():
    C()

def A():
    B()


try:
    A()
except Exception as e:
    traceback.print_exc()
"""
Traceback (most recent call last):
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module>
    A()
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A
    B()
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 9, in B
    C()
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in C
    1 / 0
ZeroDivisionError: division by zero
"""

format_exc

和print_exc一样,只不过是以字符串的形式返回,需要我们自己手动打印

import sys
import traceback


def C():
    1 / 0

def B():
    C()

def A():
    B()


try:
    A()
except Exception as e:
    tb_info = traceback.format_exc()
    print(tb_info)
"""
Traceback (most recent call last):
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module>
    A()
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A
    B()
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 9, in B
    C()
  File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in C
    1 / 0
ZeroDivisionError: division by zero
"""

标签:py,exc,灵活,python,traceback,Desktop,print,wtfpython
来源: https://www.cnblogs.com/traditional/p/11111314.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有