以下是捕获和向被调用者发送异常的常规方法
def check(a):
data = {}
if not a:
raise Exception("'a' was bad")
return data
def doSomething():
try:
data = check(None)
except Exception, e:
print e
这是另一种选择+我喜欢的一些事情:
你无需尝试/排除任何地方混乱'doSomething'功能
def check(a):
errors = []
data = {}
if not a:
errors.append("'a' was bad")
return data, errors
def doSomething():
data, errors = check(None)
if errors:
print errors
它有什么问题吗?人们的意见是什么?
答案 0 :(得分:4)
有时候第二种方法可能有用(例如,如果你正在进行一系列相对独立的操作,并且只想记录哪些方法失败了)。但是,如果你的目标是防止继续处于不正确的状态(即,不是“在发生异常时犯了试图访问数据的错误”),第二种方式并不好。如果您需要进行检查,您可能希望这样做:
def check(a):
data = {}
if not a:
raise Exception("'a' was bad")
return data
def doSomething():
data = check(None)
# continue using data
也就是说,检查一下,如果成功,就继续。您不需要使用except
“混乱”代码。如果您能以某种方式实际处理错误,则应该只使用try / except。如果你不能,那么你想要异常继续传播,如果有必要,一直传播并停止程序,因为这将阻止你继续使用{{1以无效的方式。
此外,如果在检查后仍然可以继续,但仍然“错误”访问无效data
,那么你没有做好检查。检查点(如果有的话)应该是确保只要检查没有引发异常就可以自信地进行检查。你这样做的方式,你基本上做了两次检查:你运行data
,然后你检查一个例外。相反,只需运行检查。如果失败,则引发异常。如果成功,请继续使用您的代码。如果您希望检查区分可恢复和不可恢复的错误并记录不可恢复的错误,那么只需在检查中进行记录。
当然,在许多情况下,你可以使它更简单:
check
换句话说,就是做你要做的事。如果您对def doSomething():
data.blah()
# use data however you're going to use it
执行无效操作,则会出现异常。通常没有理由单独进行明确检查。 (当然,检查肯定是有正当理由的。如果实际操作很昂贵并且可能在后期失败,那么你需要提前检查有效性,以避免浪费时间在长时间失败的操作上另一个原因可能是操作涉及I / O或某种并发性,并且可能使某些共享资源处于无效状态。)
答案 1 :(得分:1)
从现在起几年后,当你再次阅读自己的代码并试图找出你想要做的事情的时候,你会很高兴看到所有混乱的尝试 - 除了帮助使得完全明显是什么错误和数据是什么。
答案 2 :(得分:1)
此外,如果你知道'a'是唯一的错误,你可以写一个if并以这种方式处理它;你给出了这个简单的例子,这是有道理的。
但是,如果发生其他错误,则无论如何都会引发异常!
我不建议将它用作一般编程习惯,以避免尝试/除了任何地方。它在代码中确认和标记异常发生的位置。