zoukankan      html  css  js  c++  java
  • traceback:让你更加灵活地处理python的异常

    异常

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

    捕获异常

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

    python
    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对象

    python
    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模块


    print_tb

    接收一个tracebackobject

    python
    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也就是不指定,那么会打印所有层级

      python
      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_exception

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

    python
    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_exc

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

    python
    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一样,只不过是以字符串的形式返回,需要我们自己手动打印

    python
    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
    """
  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/valorchang/p/11395543.html
Copyright © 2011-2022 走看看