Python异常处理 - 行号

76 投票
10 回答
105427 浏览
提问于 2025-04-17 13:38

我正在用Python来处理一些测量数据。因为可能的结果太多了,所以处理这些结果或者组合起来很困难。有时候在评估过程中会出现错误。通常是索引错误,因为我从测量数据中取值超出了范围。

我很难找到代码中出问题的具体位置。如果我知道错误发生在哪一行,那就帮大忙了。如果我使用以下代码:

try:
    result = evaluateData(data)
except Exception, err:
    print ("Error: %s.\n" % str(err))

可惜这只告诉我出现了索引错误。我想知道更多关于这个错误的细节(比如代码中的哪一行、变量等),这样我才能搞清楚发生了什么。请问有办法吗?

谢谢。

10 个回答

30

我使用了 traceback,这个方法简单又可靠:

import traceback

try:
    raise ValueError()
except:
    print(traceback.format_exc())  # or: traceback.print_exc()

输出:

Traceback (most recent call last):
  File "catch.py", line 4, in <module>
    raise ValueError()
ValueError
44

如果你只是想获取行号,可以使用 sys 模块。如果你想要更多的信息,可以试试 traceback 模块。

import sys    
try:
    [][2]
except IndexError:
    print("Error on line {}".format(sys.exc_info()[-1].tb_lineno))

打印输出:

Error on line 3

这是来自 traceback 模块文档的一个例子:

import sys, traceback

def lumberjack():
    bright_side_of_death()

def bright_side_of_death():
    return tuple()[0]

try:
    lumberjack()
except IndexError:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print "*** print_tb:"
    traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
    print "*** print_exception:"
    traceback.print_exception(exc_type, exc_value, exc_traceback,
                              limit=2, file=sys.stdout)
    print "*** print_exc:"
    traceback.print_exc()
    print "*** format_exc, first and last line:"
    formatted_lines = traceback.format_exc().splitlines()
    print formatted_lines[0]
    print formatted_lines[-1]
    print "*** format_exception:"
    print repr(traceback.format_exception(exc_type, exc_value,
                                          exc_traceback))
    print "*** extract_tb:"
    print repr(traceback.extract_tb(exc_traceback))
    print "*** format_tb:"
    print repr(traceback.format_tb(exc_traceback))
    print "*** tb_lineno:", exc_traceback.tb_lineno
103

解决方案是打印出文件名、行号、这一行的内容以及异常的描述:

import linecache
import sys

def PrintException():
    exc_type, exc_obj, tb = sys.exc_info()
    f = tb.tb_frame
    lineno = tb.tb_lineno
    filename = f.f_code.co_filename
    linecache.checkcache(filename)
    line = linecache.getline(filename, lineno, f.f_globals)
    print 'EXCEPTION IN ({}, LINE {} "{}"): {}'.format(filename, lineno, line.strip(), exc_obj)


try:
    print 1/0
except:
    PrintException()

输出结果:

EXCEPTION IN (D:/Projects/delme3.py, LINE 15 "print 1/0"): integer division or modulo by zero

撰写回答