捕获异常想必都不陌生,但是你真的捕获的恰当吗?对解决bug有帮助吗?还是说帮了倒忙?还是说加了几行无用的代码?
exception 是流程控制, 用来代替没有 exception 机制语言的返回码机制。不是所有的异常都要抓取,应该只抓取你关心或当前 code 能处理的异常,其它的都向上丢。
------ by leader comment
接下来看下几种异常捕获的方式:
第一种:
def exception():
print 2 / 0
if __name__ == "__main__":
try:
exception()
except Exception:
raise Exception("some_code failed!")
抛出的异常:
➜ python python exception.py
Traceback (most recent call last):
File "exception.py", line 18, in <module>
raise Exception("some_code failed!")
Exception: some_code failed!
从抛出的异常来看"some_code failed"不是我们想要的吧,最正确的提示应该是告诉我们分母不应该是0,
而且这种方式会把some_code()的错误全部隐藏,看不到traceback和真正的错误是什么,无疑帮了倒忙,所以这种方式不可取。
第二种:
def exception():
print 2 / 0
def func1():
exception()
if __name__ == "__main__":
try:
func1()
except Exception:
import traceback
traceback.print_exc()
抛出的异常:
➜ python python exception.py
Traceback (most recent call last):
File "exception.py", line 17, in <module>
func1()
File "exception.py", line 12, in func1
exception()
File "exception.py", line 8, in exception
print 2 / 0
ZeroDivisionError: integer division or modulo by zero
第二种方式比第一种方式好一丢丢,会把错误信息报出来,但是并没有输出到日志中,只是控制台打印输出,而且也没把错误向上抛出。
第三种:
def exception():
print 2 / 0
if __name__ == "__main__":
try:
exception()
except Exception:
raise
抛出的异常:
➜ python python exception.py
Traceback (most recent call last):
File "exception.py", line 13, in <module>
exception()
File "exception.py", line 8, in exception
print 2 / 0
ZeroDivisionError: integer division or modulo by zero
第三种方式好像终于获得了我们想要的错误,并且向上抛出了,但是有没有发现这种抛出的方式跟没try catch 一样。往下看:
def exception():
print 2 / 0
if __name__ == "__main__":
exception()
抛出的异常:
➜ python python exception.py
Traceback (most recent call last):
File "exception.py", line 13, in <module>
exception()
File "exception.py", line 8, in exception
print 2 / 0
ZeroDivisionError: integer division or modulo by zero
一样吧~ 那既然一样何必要加那几行try catch,所以第三种还是有瑕疵,
看最后一种:
class MyException(Exception):
pass
def exception():
print 2 / 0
if __name__ == "__main__":
try:
exception()
except Exception:
import sys
exc_info = sys.exc_info()
raise MyException('This is bug'), None, exc_info[2]
抛出的异常:
➜ python python exception.py
Traceback (most recent call last):
File "exception.py", line 11, in <module>
exception()
File "exception.py", line 6, in exception
print 2 / 0
__main__.MyException: This is bug
嗯,完美了!
不仅抛出了自己定义的异常,本身的报错栈也一目了然!如果自定义的exception不恰当还可以看Traceback。
每种语言都有捕获异常的方式,合理的运用事半功倍。不管用什么语言,在捕获异常的时候不要觉得自己定义的异常很完美,你以为的异常等真出错了不一定是你以为的,线上出了问题只看见个"This is bug",你什么心情?so 在捕获异常的时候尽量把自定义的和原本的报错也加上。
本文参考:
http://www.ianbicking.org/blog/2007/09/re-raising-exceptions.html
http://xcodest.me/How_to_raise_python_exception.html
网友评论