假设我有一个功能:
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()是成功还是失败?
答案 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