我如何让python函数返回异常追溯或结果?

时间:2016-03-12 03:08:15

标签: python python-2.7

假设我有一个功能:

def ReadFile():
    with open("/etc/passwd") as file:
        data = file.read()

这个函数可能会成功,在这种情况下它需要返回一个结果,或者它可能会失败,在这种情况下我想返回一个异常的回溯,它会通过电子邮件发送给我,所以我知道我的程序失败了什么失败了。

要做到这一点,我可以做类似的事情:

import traceback

def ReadFile():
    try:
        with open("/etc/passwd") as file:
            data = file.read()
    except IOError:
        return traceback.format_exc()
    return data

如果能够成功读取文件,则返回文件的内容。否则,它返回异常的回溯。

traceback.format_exc()返回一个字符串。如果ReadFile()应该返回一个列表,或者如果成功则返回元组或整数,那么事情很容易 - 当你调用ReadFile()时,如果返回的结果是一个字符串,你知道它失败了你可以运行代码发送电子邮件你错了,如果结果是你期望的类型(int,tuple,list或w / e),那么你知道它的效果。

如果ReadFile()应该返回一个字符串,就像在我的例子中那样,而不是确定ReadFile()是成功还是失败变得非常困难,因为你需要解析字符串以确定它是否看起来像回溯或您期望的结果。

有更好的方法吗?也许某些方法让traceback返回某种类型的对象,其中包含与traceback.format_exc()包含的信息相同的信息,以便更容易确定ReadFile()是成功还是失败?

3 个答案:

答案 0 :(得分:3)

我建议,不要在此方法中捕获异常,而是让它引发异常并从您调用的任何地方捕获它。

换句话说,不要把try catch放在那个方法中。将try catch放在调用该方法的任何地方,并捕捉它可能引发的内容。

所以,请改为:

import traceback

def ReadFile():
    with open("/etc/passwd") as file:
        data = file.read()
    return data

try:
    r = ReadFile()
except IOError:
    traceback.format_exc()
    # or log or whatever operation

或者,如果您确实希望在该方法中处理异常并希望返回某种“失败”信号,那么您应该返回异常对象并查看它是否存在。

所以,你也可以这样做。在您调用方法时,在引发时返回Exception对象并检查它是否存在异常

def ReadFile():
    try:
        with open("/etc/passwd") as file:
            data = file.read()
    except IOError as exc:
        return exc
    return data

if isinstance(r, Exception):
    # do exception things here

但我会选择第一个选项。

答案 1 :(得分:2)

已经例外"返回"对于封闭范围,这就是为什么首先存在例外的全部原因。

# See how simple this is?
def read_file():
    with open('/etc/passwd') as file:
        return file.read()

然后,您可以在调用链中的适当位置处理异常,但只在适当的位置 。对于您希望以特定方式处理的预期异常,请在有足够信息正确处理它们的位置处理它们。对于一般例外,在顶级事件循环中处理它们,或者只是将它们传播并让解释器将它们打印出来。

与大多数其他事情一样,您希望处理异常的确切方式因程序而异。但是将异常作为函数结果返回会产生反作用。

答案 2 :(得分:2)

如果要返回异常对象,可以执行以下操作:

def ReadFile():
    try:
        with open("/etc/passwd") as file:
            data = file.read()
    except IOError as ex:
        return ex
    return data

然而,正如Ismail所说,最好让它像

一样抛出异常
def ReadFile():
    with open("/etc/passwd") as file:
        return file.read()

... # Some code that eventually calls the function
...
try:
    data = ReadFile()
except IOError:
    print("File read failed")
    ... # Handle error