【问题标题】:How does one avoid a long stack trace when errors are raised in recursive functions?当递归函数中出现错误时,如何避免长堆栈跟踪?
【发布时间】:2013-11-16 12:08:16
【问题描述】:

考虑以下函数:

def fact(x):

    if x == 1:
        return 1

    if x == 2:
        raise Exception("some error")

    return fact(x-1) * x

调用fact(100) 将产生一个堆栈跟踪,其中包含对“fact”函数的 100 个引用。如何简化堆栈跟踪以帮助调试?可以改变一些东西来避免这个大堆栈吗?

注意:这是我根据前段时间编写的一些代码提出的假设情况。

【问题讨论】:

  • 为什么不直接滚动到最后?这就是总是的主要原因。
  • 这就是我目前所做的!不知道有没有更好的解决办法?
  • 不幸的是,没有。最好的办法是使用 pydev 中的调试器。

标签: python exception logging recursion


【解决方案1】:

你可以试试traceback

这里我写了一些测试代码。用Python 3.3.2测试过

import sys
import traceback

def fact(x):
    if x == 0:
        raise Exception("test exception")
    else:
        return fact(x - 1)

def main():
    fact(5)

if __name__ == "__main__":
    try:
        main()
    except:
        (_type, _value, _traceback) = sys.exc_info()
        tb = traceback.extract_tb(_traceback)
        lst = traceback.format_list(tb) 
        lst += [""] # assuming there was no "" in lst
        last_str = None
        last_count = 0
        for s in lst:
            if s == last_str:
                last_count += 1
            else:
                if last_str == None:
                    print(s, end="")
                else:
                    if last_count > 2:
                        print("...omitted %d same items"%(last_count - 2))
                    if last_count > 1:
                        print(last_str, end="")
                    print(s, end="")
                last_str = s
                last_count = 1

测试输出:

  File "test.py", line 15, in <module>
    main()
  File "test.py", line 11, in main
    fact(5)
  File "test.py", line 8, in fact
    return fact(x - 1)
...omitted 3 same items
  File "test.py", line 8, in fact
    return fact(x - 1)
  File "test.py", line 6, in fact
    raise Exception("test exception")

【讨论】:

    【解决方案2】:

    如果您在 3-arg catch 中捕获异常或调用 sys.exc_info(),则可以访问回溯对象,并且可以使用 .tb_next 字段一直向上。您可以在重新引发异常的基础上以任何您喜欢的方式构造另一组回溯。

    【讨论】:

      猜你喜欢
      • 2013-06-28
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 2011-08-15
      • 2018-09-19
      • 1970-01-01
      相关资源
      最近更新 更多