![eb4ead5f11ec7620ceacedbe9da840fd.png](https://img-blog.csdnimg.cn/img_convert/eb4ead5f11ec7620ceacedbe9da840fd.png)
1.基本异常处理方式
多层嵌套try catch只能捕获到异常,无法处理,无法溯源。
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s)*2
def main():
try:
bar('0')
except Exception as e:
print('Error:',e)
finally:
print('end')
main()
Error: division by zero
end
2.解释器打印异常
如果未捕获异常,异常就会一直上抛,被解释器捕获并打印错误信息,然后退出程序。
通过解释器打印的错误信息可以看到函数整个调用栈:
- 首先告知第八行main()出错
- 在main()函数中是第六行bar()函数出错
- 在bar()函数中是第四行foo()函数出错
- 在foo中是第二行出错
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s)*2
def main():
bar("0")
main()
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-1-3d66a9ef6914> in <module>
6 bar("0")
7
----> 8 main()
<ipython-input-1-3d66a9ef6914> in main()
4 return foo(s)*2
5 def main():
----> 6 bar("0")
7
8 main()
<ipython-input-1-3d66a9ef6914> in bar(s)
2 return 10 / int(s)
3 def bar(s):
----> 4 return foo(s)*2
5 def main():
6 bar("0")
<ipython-input-1-3d66a9ef6914> in foo(s)
1 def foo(s):
----> 2 return 10 / int(s)
3 def bar(s):
4 return foo(s)*2
5 def main():
ZeroDivisionError: division by zero
3.sys.exc_info和traceback object
Python程序的traceback信息均来源于一个叫做traceback object的对象,而这个traceback object通常是通过函数sys.exc_info()来获取的,先来看一个例子:
import traceback
import sys
def func():
raise SyntaxError("-- func exception --")
def main():
try:
func()
except Exception as e:
exc_type, exc_value, exc_obj = sys.exc_info()
#sys.exc_info()获取了当前处理的exception的三个相关信息:类型,value值,traceback object
#以元组返回
print("exception_type: t%s,nexception_value: t%s,nexception_object: t%s,n"
%(exc_type,exc_value,exc_obj))
if __name__ == "__main__":
main()
exception_type: <class 'SyntaxError'>,
exception_value: -- func exception --,
exception_object: <traceback object at 0x07218C28>,
4.traceback module
4.1 print_tb
traceback.print_tb(tb[, limit[, file]]) tb:这个就是traceback object, 是我们通过sys.exc_info获取到的
limit:这个是限制stack trace层级的,如果不设或者为None,就会打印所有层级的stack trace
* file:这个是设置打印的输出流的,可以为文件,也可以是stdout之类的file-like object。如果不设或为None,则输出到sys.stderr。
import traceback
import sys
def func():
raise Exception("-- func exception --")
def main():
try:
func()
except Exception as e:
exc_type, exc_value, exc_obj = sys.exc_info()
traceback.print_tb(exc_obj)
if __name__ == "__main__":
main()
File "<ipython-input-4-d32102c7a353>", line 9, in main
func()
File "<ipython-input-4-d32102c7a353>", line 5, in func
raise Exception("-- func exception --")
4.2 print_exception
traceback.print_exception(etype, value, tb[, limit[, file]]) 跟print_tb相比多了两个参数etype和value,分别是exception type和exception value,加上tb(traceback object),正好是sys.exc_info()返回的三个值 另外,与print_tb相比,打印信息多了开头的"Traceback (most...)"信息以及最后一行的异常类型和value信息 * 还有一个不同是当异常为SyntaxError时,会有"^"来指示语法错误的位置
import traceback
import sys
def func():
raise Exception("-- func exception --")
def main():
try:
func()
except Exception as e:
exc_type, exc_value, exc_obj = sys.exc_info()
traceback.print_exception(exc_type,exc_value,exc_obj,limit=2,file=sys.stdout)
if __name__ == "__main__":
main()
Traceback (most recent call last):
File "<ipython-input-5-31512e045386>", line 9, in main
func()
File "<ipython-input-5-31512e045386>", line 5, in func
raise Exception("-- func exception --")
Exception: -- func exception --
4.3 print_exc
print_exception()的简化版,自动进行exc_info的操作。
定义:
traceback.print_exc([limit[, file]])
import traceback
import sys
def func():
raise Exception("-- func exception --")
def main():
try:
func()
except Exception as e:
#exc_type, exc_value, exc_obj = sys.exc_info()
traceback.print_exc(limit=2,file=sys.stdout)
if __name__ == "__main__":
main()
Traceback (most recent call last):
File "<ipython-input-15-63e0554ab613>", line 9, in main
func()
File "<ipython-input-15-63e0554ab613>", line 5, in func
raise Exception("-- func exception --")
Exception: -- func exception --
4.4 format_exc
类似于print_exc(limit)
将exc_info 以字符串的形式返回 定义:
traceback.format_exc([limit])
import traceback
import sys
def func():
raise Exception("-- func exception --")
def main():
try:
func()
except Exception as e:
exc_type, exc_value, exc_obj = sys.exc_info()
serror = traceback.format_exc(limit=1)
print(type(serror),"n",serror)
if __name__ == "__main__":
main()
<class 'str'>
Traceback (most recent call last):
File "<ipython-input-11-c31b5de91e3e>", line 12, in main
func()
Exception: -- func exception --
总结
- 多层嵌套try catch只能捕获到异常,无法处理,无法溯源
- 如果未捕获异常,异常就会一直上抛,被解释器捕获并打印错误信息,然后退出程序。
- raise作用是不对捕获到的异常进行任何处理,直接抛出。
- sys.exc_info()被用来获取被捕获的异常的相关信息,以元组形式返回。
- traceback.print_tb(tb[, limit[, file]]),向file输出以limit为回溯次数限制的exc_obj
- traceback.print_exception(etype, value, tb[, limit[, file]]),除了输出obj外,还加上了type:value
- traceback.print_exc([limit[, file]]), 前者的简化版,最常用,输出obj+type:value 且集成了sys.exc_info()的功能。
- traceback.format_exc([limit]), 和前者类似,将输出转变为返回相应字符串。