Python异常处理 - 行号

时间:2013-01-25 09:47:57

标签: python exception indexing

我正在使用python来评估一些测量数据。由于许多可能的结果,难以处理或可能的组合。有时在评估期间会发生错误。它通常是一个索引错误,因为我超出了测量数据的范围。

很难找到问题发生在代码中的哪个位置。如果我知道错误被引发到哪一行,那将会有很大帮助。如果我使用以下代码:

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

不幸的是,这只会告诉我存在索引错误。我想知道有关异常的更多细节(代码行,变量等),以了解发生了什么。有可能吗?

谢谢。

7 个答案:

答案 0 :(得分:63)

解决方案,打印文件名,亚麻,行本身和异常描述:

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

答案 1 :(得分:21)

要简单地获取可以使用sys的行号,如果您想要更多,请尝试使用traceback模块。

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

打印

Error on line 3

Example from the traceback module documentation

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

答案 2 :(得分:7)

最简单的方法就是使用:

import traceback
try:
    <blah>
except IndexError:
    traceback.print_exc()

或者如果使用日志记录:

import logging
try:
    <blah>
except IndexError as e:
    logging.exception(e)

答案 3 :(得分:3)

我使用的是简单而健壮的traceback

import traceback

try:
    raise ValueError()
except:
    print(traceback.format_exc())

出局:

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

答案 4 :(得分:1)

为调用堆栈中的最后一项提供文件、行号和异常

from sys import exc_info
from traceback import format_exception


def print_exception():
    etype, value, tb = exc_info()
    info, error = format_exception(etype, value, tb)[-2:]
    print(f'Exception in:\n{info}\n{error}')

try:
    1 / 0
except:
    print_exception()

印刷品

Exception in:
   File "file.py", line 12, in <module>
    1 / 0

ZeroDivisionError: division by zero

答案 5 :(得分:0)

我建议使用python日志记录库,它有两个有用的方法,在这种情况下可能会有所帮助。

  1. logging.findCaller()

    • findCaller(stack_info = False)-仅报告前一个调用方的行号,导致引发异常
    • findCaller(stack_info = True)-报告前一个调用方的行号和堆栈,导致引发异常
  2. logging.logException()

    • 报告在try / except块中引发异常的行和堆栈

有关更多信息,请查看api https://docs.python.org/3/library/logging.html

答案 6 :(得分:0)

我总是使用此代码段

import sys, os

try:
    raise NotImplementedError("No error")
except Exception as e:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
    print(exc_type, fname, exc_tb.tb_lineno)

对于不同的观点和可能的问题,您可以参考When I catch an exception, how do I get the type, file, and line number?