这是捕获异常并将其抛出给被调用者的正常方法
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
这是一个替代方案 + 一些我喜欢的东西:
- 'data' 始终存在,'check' 函数可以设置一些 数据的默认值,然后将逻辑包含在函数中 并且不必重复。也意味着开发人员不能在发生异常时尝试访问数据。 (数据可以在“doSomething”函数的最顶部定义+分配一些默认值)
您不必到处都使用 try/excepts 来打乱“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
有什么问题吗?人们的意见是什么?
请您参考如下方法:
有时第二种方法会很有用(例如,如果您正在执行一系列相对独立的操作并且只想记录哪些操作失败了)。但是,如果您的目标是防止在不正确的状态下继续(即,而不是“在发生异常时犯下试图访问数据的错误”),则第二种方法并不好。如果您需要进行检查,您可能希望这样做:
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。如果不能,那么你希望异常继续传播,如果有必要,一路向上传播并停止程序,因为那样会阻止你继续使用数据以无效方式。
此外,如果检查后可以继续但仍然“犯错误”访问无效的data,那么您没有进行很好的检查。检查的要点(如果有的话)应该是确保只要检查不引发异常,您就可以自信地继续进行。您这样做的方式基本上是检查两次:运行 check,然后检查异常。相反,只需运行检查。如果失败,则引发异常。如果成功,请继续您的代码。如果您希望检查区分可恢复和不可恢复的错误并记录不可恢复的错误,那么只需在检查中进行日志记录即可。
当然,在很多情况下你可以让它更简单:
def doSomething():
data.blah()
# use data however you're going to use it
换句话说,就是做你想做的事。如果你对 data 做了一些不起作用的事情,你就会得到一个异常。通常没有理由进行单独的显式检查。 (当然,检查肯定有正当理由。一个是如果实际操作代价高昂并且可能在后期失败,所以你想预先检查有效性以避免浪费时间在长时间后会失败的操作上计算。另一个原因可能是如果操作涉及 I/O 或某种并发,并且可能使某些共享资源处于无效状态。)
