r = 10 / int("a")print("result:", r)except ValueError as e:print("ValueError:", e)except ZeroDivisionError as e:print("ZeroDivisionError:", e)finally:print("finally...")print("END...")
int()函数可能会抛出ValueError,所以我们用一个except捕获ValueError,用另一个except捕获ZeroDivisionError
此外,如果没有错误发生,可以再except语句块后面加一个else,当没有错误发生时,会自动执行else语句 。try:print("try...")
r = 10 / int("2")print("result:", r)except ValueError as e:print("ValueError:", e)except ZeroDivisionError as e:print("ZeroDivisionError:", e)else:print("No error!")finally:print("finally...")print("END")
python的错误其实也是class , 所有的错误类型都继承自BaseException,
所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽” 。
比如:try:
foo()except ValueError as e:print("ValueError")except UnicodeError as e:print("UnicodeError")
第二个except永远也捕获不到UnicodeError, 因为UnicodeError是ValueError的子类
如果有,也是被第一个except给捕获了 。
python所有的错误都是BaseException类派生的 。
所有常见的错误类型和继承关系看这里:
使用try...exccept捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用foo()
foo()调用bar() , 结果bar()出错了,这时,只要main()捕获到了,就可以处理:def foo(s):return 10 / int(s)def bar(s):return foo(s) * 2def main():try:
bar("0")except Exception as e:print("Error:", e)finally:print("finally...")
也就是说,不需要在每个可能出错的地方去捕获异常,只要在合适的层次去捕获就可以了 。
这样一来,就大大减少了写 try...except...finally的麻烦 。
二、调用堆栈
如果错误没有被捕获,他就会一直往上抛,最后被python解释器捕获,打印一个错误信息,然后程序退出 。def foo(s):return 10 / int(s)def bar(s):return foo(s) * 2def main():
bar("0")
main()
执行结果为:
Traceback (most recent call last):
File "C:/Python36/test.py", line 10, in module
main()
File "C:/Python36/test.py", line 8, in main
bar("0")
File "C:/Python36/test.py", line 5, in barreturn foo(s) * 2
File "C:/Python36/test.py", line 2, in fooreturn 10 / int(s)
ZeroDivisionError: division by zero
出错并不可怕,可怕的时不知道哪里出错了 。解读错误信息时定位错误的关键 。
我们从上往下可以看到整个错误的调用函数链 。
错误第一行:
Traceback (most recent call last):
这告诉我们的是错误的跟踪信息 。
File "C:/Python36/test.py", line 10, inmodule main()
说明调用main()出错了,在代码文件test.py中第10行,但是原因是第8行:
File"C:/Python36/test.py", line8, in main
bar("0")
调用bar("0")出错了 , 在代码文件test.py中第8行,但原因是第5行:
File"C:/Python36/test.py", line5, in barreturn foo(s) * 2调用return foo(s) * 2时出错了,在test.py中第5行,但原因是第2行
File "C:/Python36/test.py", line 2, in fooreturn 10 / int(s)
ZeroDivisionError: division by zero
这时我们找到了源头,原来在第2行调用return 10 / int(s)出错了,错误为ZeroDivisionError
三、记录错误
如果不捕获错误,自然可以让python解释器来打印出错误堆栈,但是程序也被结束了 。
既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去 。
python内置的logging模块可以非常容易地记录错误信息:import loggingdef foo(s):return 10 / int(s)def bar(s):return foo(s) * 2def main():try:
bar("0")except Exception as e:
推荐阅读
- 安卓手机怎么玩苹果账号,安卓手机玩苹果账号的王者荣耀
- 图美社小程序怎么注册,美图社交平台
- edb系统erp,edb系统故障
- 视频号直播业务,视频号直播有收入吗
- php禁止不提交数据访问 phpstudy禁止访问
- paintnet安装特别慢,paintnet软件
- 代码注释java,代码注释自动生成
- 拍摄指南讲课什么,拍摄指南是哪的书
- java写查询代码 java查询简单代码