抛出异常,包括额外的信息

时间:2012-12-02 20:10:49

标签: python

我有一些解析文件的代码。它很简单,就像这样:

for line in config_file:
    line_split=line.split("|")
    pid_index = int(line_split[3])
    date_locations = [int(i) for i in line_split[2].split(",")]
    in_file = line_split[0]
    out_file = line_split[1]
    file_info.append([in_file, out_file, date_locations, pid_index])

如果出现问题,我希望Python继续打印其常见的错误消息,但我想在常规错误消息的末尾添加一行,如:

except:
    print "line \"{0}\"  might have failed to parse".format(line.rstrip())

但是,使用上面的代码只显示额外的信息行 - 会覆盖常规错误消息!

我尝试将以下内容添加到我的catch中,但它会产生难看的输出:

e = sys.exc_info()
for i in e:
    print i

是否有一种简单的方法让Python打印常规错误消息以及我选择的其他信息?

3 个答案:

答案 0 :(得分:3)

我认为这里最好的选择(我在此编辑中移除了我的其他解决方案,因为我觉得它实际上并不是很好)是创建自己的异常来描述您的问题,然后在顶部使用它您有例外:

class ParseFailureError(Exception):
    def __init__(self, line):
        self.line = line.rstrip()

    def __str__(self):
        return "line \"{0}\"  might have failed to parse".format(self.line)

然后:

try:
    ...
except SomeException as exception:
    raise ParseFailureError(line) from exception

这会产生类似的东西:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: name 'x' is not defined

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
__main__.ParseFailureException: line "blah" might have failed to parse

(我使用NameError作为示例的SomeError

请注意,我已在您的except行中添加了一个特定的例外情况 - 这总是值得的,因为捕获任何异常都可能导致您忽略您不想要的错误。

此方法的优点是可以让您的代码更容易被其他软件使用,因为它们可以捕获此特定异常。

异常上的from语法告诉Python异常的根本原因。否则,Python将假定新异常是在处理异常期间发生的错误。请注意,这仅适用于Python 3.x,在早期版本中,您必须手动执行此操作。我建议使用traceback.format_exc()然后将其打印为您的例外错误消息的一部分。

答案 1 :(得分:2)

except可以抑制错误。你想抓住它来打印你的额外消息 - 然后让它再次回来。你这样做

try:
    raise ValueError("I do not like green eggs and ham")
except ValueError as e:
    print("OK, actually I do.")
    raise

在Python 2.x中,一次只能抛出一个异常。在Python 3中,您可以

raise ValueError("OK, actually I do.") from e

表示此错误是由前一个错误引起的。

答案 2 :(得分:2)

您可以使用logging module

import sys
import logging
logging.basicConfig(level = logging.DEBUG)
logger = logging.getLogger(__name__)

config_file = """\
foo bar
""".splitlines()
try:
    for line in config_file:
        line_split=line.split("|")
        pid_index = int(line_split[3])
        date_locations = [int(i) for i in line_split[2].split(",")]
        in_file = line_split[0]
        out_file = line_split[1]
        file_info.append([in_file, out_file, date_locations, pid_index])
except IndexError as err:
    logger.exception('line {l!r} might have failed to parse'.format(
        l = line.rstrip()))    
    sys.exit()

产量

ERROR:__main__:line 'foo bar' might have failed to parse
Traceback (most recent call last):
  File "/home/unutbu/pybin/test2.py", line 15, in <module>
    pid_index = int(line_split[3])
IndexError: list index out of range