异常处理
无论在何种编程语言中,都会碰到程序异常,有些是因为代码错误导致的不可预见性异常,这个要去调用栈检查。
而另一类异常是由程序员故意设置的异常,用于提醒用户或后面的程序。
在Python中默认的异常处理是解释器运行遇到错误时,一直向上返回到程序顶层,启用默认的处理器即打印出错信息到屏幕。
还有捕获异常,通过try/except语句在程序内启动异常处理器,此时异常不会一直向上返回。
另一种是触发异常,即raise、assert语句,raise语句用来直接触发异常,assert语句用来做判断,若判断不通过则触发异常。
编程者也能自定义异常,从内置异常类Exception继承。
try/except和try/finally
前者用于捕获异常并从异常中恢复,即不中断主程序。
后者用于提供终止行为,即无论是否出错都会执行的行为,并且如果有异常,也会先执行finally代码后再向上返回异常。
try/except/else
用于捕捉异常,主程序在try中,并且如果没有异常,则会执行else语句中的代码,否则不执行。
在2.5以后的版本中,else可以与finally组合使用,并且至少有except语句的时候才能使用else。
单独raise语句用于重新引发当前异常
assert语句与测试模式
在代码中使用__debug__
判断并执行raise语句用于测试,在编译时调用-O
参数可以移除assert语句的字节码
扫描二维码关注公众号,回复:
2642761 查看本文章
with/as用于替代try/finally语句,并且支持更丰富的协议
- 计算表达式,所得到的对象称为环境管理器,必须有__enter__和__exit__方法
- 环境管理器的__enter__方法会被调用,如果as子句存在,其返回值会赋值给as子句中的变量,否则直接丢弃
- 代码块中嵌套的代码会执行
- 如果with代码引发异常,__exit__(type, value, traceback)方法会被调用。异常重新引发,传递到with外
- 如果with代码没有异常,__exit__依然调用,其参数都以None传递。
class TraceBlock:
def message(self, arg):
print('running', arg)
def __enter__(self):
print('running with block')
return self
def __exit__(self, exc_type, exc_value, exc_tb):
if exc_type is None:
print('Exited normally\n')
else:
print('Raise an exception!', exc_type)
return False
with TraceBlock() as action:
action.message('test 1')
print('reached')
with TraceBlock() as action:
action.message('test 2')
raise TypeError
print('not reached')
错误是异常,但异常不一定是错误。