如何将python回溯限制为特定文件

时间:2015-08-11 18:52:38

标签: python debugging traceback

我编写了很多使用外部库的Python代码。我经常写一个bug,当我运行代码时,我会在Python控制台中获得一个很长的回溯。 99.999999%的时间是由于我的代码中的编码错误,而不是因为包中的错误。但是回溯一直到程序包代码中的错误行,要么需要大量滚动回溯来查找我编写的代码,要么回溯是如此深入到我自己的代码所没有的包中#&# 39;甚至出现在追溯中。

有没有办法去"黑盒"包代码,或以某种方式只显示我的代码中的追溯线?我希望能够向系统指定我想要追溯的目录或文件。

2 个答案:

答案 0 :(得分:15)

为了打印自己的堆栈跟踪,您需要自己处理所有未处理的异常;这就是sys.excepthook变得方便的方式。

此功能的签名是sys.excepthook(type, value, traceback),其工作是:

  

此函数将给定的追溯和例外打印到sys.stderr

因此,只要您可以使用追溯并且只提取您关心的部分,您应该没问题。测试框架经常这样做;它们具有自定义assert函数,这些函数通常不会出现在回溯中,换句话说,它们会跳过属于测试框架的框架。此外,在这些情况下,测试通常也由测试框架启动。

你最终会得到一个如下所示的追溯:

[ custom assert code ] + ... [ code under test ] ... + [ test runner code ]

如何识别您的代码。

您可以为代码添加全局:

__mycode = True

然后识别帧:

def is_mycode(tb):
  globals = tb.tb_frame.f_globals
  return globals.has_key('__mycode')

如何提取框架。

  1. 跳过与您无关的帧(例如自定义断言代码)
  2. 确定您的代码中有多少帧 - > length
  3. 提取length

    def mycode_traceback_levels(tb):
      length = 0
      while tb and is_mycode(tb):
        tb = tb.tb_next
        length += 1
      return length
    
  4. 示例处理程序。

    def handle_exception(type, value, tb):
      # 1. skip custom assert code, e.g.
      # while tb and is_custom_assert_code(tb):
      #   tb = tb.tb_next
      # 2. only display your code
      length = mycode_traceback_levels(tb)
      print ''.join(traceback.format_exception(type, value, tb, length))
    

    安装处理程序:

    sys.excepthook = handle_exception
    

    下一步是什么?

    如果您仍想了解失败在您自己的代码之外的位置的某些信息,则可以调整length以添加一个或多个级别。

    另见https://gist.github.com/dnozay/b599a96dc2d8c69b84c6

答案 1 :(得分:2)

traceback.extract_tb(tb)将以格式(file,line_no,type,error_statement)返回错误帧元组,您可以使用它来格式化回溯。另请参阅https://pymotw.com/2/sys/exceptions.html

import sys
import traceback

def handle_exception(ex_type, ex_info, tb):
    print ex_type, ex_info, traceback.extract_tb(tb)

sys.excepthook = handle_exception