异常处理
在程序运行的过程中,如果发生了错误,可以用try…except…finally…的错误处理机制,判断是否有错,以及找到出错的原因。
try...
except: division by zero
finally...
END
当我们认为某些代码可能会出错时,就可以用try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,如果有finally语句块,则执行finally语句块,至此,执行完毕。
Python的错误其实也是class,所有的错误类型都继承自BaseException,所以在使用except时需要注意的是父类和子类同时存在时,子类不会捕获错误。下面因为UnicodeError是ValueError的子类所以不会捕获到错误。
try:
foo()
except ValueError as e:
print('ValueError')
except UnicodeError as e:
print('UnicodeError')
分析错误
- 调用栈
如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,如下是错误信息
Traceback (most recent call last):
File "err.py", line 11, in <module>
main()
File "err.py", line 9, in main
bar('0')
ZeroDivisionError: division by zero
第一个错误表示 11行调用main方法出错,第二个错误表示调用bar(‘0’)出错了
- 记录错误
Python内置的logging模块可以非常容易地记录错误信息,程序打印完错误信息后会继续执行,并正常退出,通过配置,logging还可以把错误记录到日志文件里,方便事后排查。
import logging
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar('0')
except Exception as e:
logging.exception(e)
main()
print('END')
- 抛出错误
用raise语句抛出一个错误的实例
class FooError(ValueError):
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)
return 10 / n
foo('0')