1、异常
例如:
def fetcher(obj,index):
return obj[index]
def catcher():
try:
fetcher(x,4)
except IndexError:
print('got exception')
print('continuing')
2、引发异常
raise IndexError
3、用户定义的异常: 用户定义的异常继承自内置异常类Exception
class Bad(Exception):
pass
4、try/finally
如果try部分没有发生异常,则finally中部分会执行,finally后面也会执行。如果try部分发生异常,则在finally中的部分会执行,finally后面部分不执行。
5、try/except/else语句
try:
statement
except name1:
statements
except (name2,name3):
statements
except name4 as data:
statements
except :
statements
else: #没有发生异常时,执行这部分
statements
解释
except: #捕获所有异常
except name: 捕获特定异常
except name,value: 捕获所列异常和额外的数据
except (name1,name2): 捕获列出的异常
except (name1,name2) value: 捕获列出的异常,并取得额外的数据
else: 如果没有发生异常,就运行
finally: 总是会运行此代码
Exception的异常几乎与一个空的except具有相同的效果,但是忽略和系统退出相关的异常:
try:
ation()
except Exception:
...
6、统一try/except/finally语句
try:
main-action
except Exception1:
handler1
except Exception2:
handler2
else:
else-block
finally:
finally-block
无论发生什么,当main-action代码完成时,而任何引发的异常都已处理后,finally-block就会被执行。事实上,即使异常处理器或者else-block内部有错误发生而引发的新的异常,finally-block内部代码依然会执行
就像往常一样,finally字句并没有终止异常,当finally-block执行时,如果异常还在,就会在finally-block代码执行后继续传递。而控制权会跳至程序其他地方(到另外一个try,或者默认顶层处理器)如果finally执行时,没有异常处于激活状态,控制权就会在整个try语句之后继续执行。
7、raise语句
raise <instance> #抛出一个类的实例
raise <class> #产生一个类的实例并抛出
raise #重新抛出最近最常用的异常
例如:
raise IndexError #class (instance create)
raise IndexError #instance(create in statement)
如果一个try包含了一个名为except name as X:字句,变量x将会分配给引发中提供的实例:
try :
...
except IndexError as X: #x被赋予成IndexError的实例
...
利用raise传递异常
raise语句不包括异常名称或额外数据值时,就是重新引发当前异常。如果需要捕捉异常和处理一个异常,又不希望异常在程序中死掉时,一般就会使用这种形式。
例如:
try:
raise IndexError('spam')
except IndexError:
print('propagating')
raise
通过这种方式执行raise时,会重新引发异常,并将其传递给更高层的处理器(或者顶层的默认处理器,他会停止程序,打印标准错误消息) 。
8、python3.0异常链:raise from
raise exception from otherexception
当使用from的时候,第二个表达式指定了另一个异常类或实例,他会附加到引发异常的__cause__属性。如果引发的异常没有捕获,python把异常也作为标准出错信息的一部分打印出来。
9、assert语句
assert <test>,<data>
1、assert语句用来声明某个条件是真的。
2、如果你非常确信某个你使用的列表中至少有一个元素,而你想要检验这一点,并且在它非真的时候引发一个错误,那么assert语句是应用在这种情形下的理想语句。
3、当assert语句失败的时候,会引发一AssertionError。
10、with/as环境管理器
在python2.6和python3.0中引入了一种新的异常相关的语句
如果想在python2.5中使用的话,必须使用如下语句来激活
from __future__ import with_statement
基本使用
with expression [as varible]:
with-block
11、环境管理协议
1、计算表达式,所得到的对象称为环境管理器,它必须有__enter__和 __exit__方法
2、环境管理器的__enter__方法会被调用,如果as字句存在,其返回值会赋值给as子句中的变量,否则抛弃。
3、代码嵌套代码会执行
4、如果with代码块引发异常,__exit__(type,value,traceback)方法会被调用.这些也是由sys.exc_info返回相同的值。否则 异常会终止。正常情况下异常应该重新引发,这样的话才能传递到with语句之外
5、如果with代码没有引发异常,__exit__方法依然会被调用,其type,value以及traceback参数都会以 None传递
例如:
class TraceBlock:
def message(self,arg):
print('running',arg)
def __enter__(self):
print('starting 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')
12、内置Exception类
BaseException 异常的顶级根类。这个类不能当作用户定义的类直接继承(使用Exception)。它提供了子类所继承的默认的打印和状态保持行为。如果在这个类的一个实例上调用str内置函数时,该类返回创建实例的时候所传递的构造函数的显示字符串(如果没有参数的话,返回一个空字符串),此外除非子类替换了这个类的构造函数,在实例构造时候传递给这个类的所有参数都将作为一个元组存储在args属性中
Exception 与应用相关的异常的顶层超类。这是BaseException的一个直接子类,并且是所有其他内置异常类的超类,除了系统退出实践之类(SystemExit.KeyboardInterrupt和GenatorExit)。几乎所有用户定义的类都应该继承自这个类,而不是BaseException。当遵循这个惯例的时候,在一条try预计的处理器中指名Exception,确保你的程序将捕获出系统退出事件之外的所有异常,通常该事件是允许通过的。实际上,Exception变成了try预计中的一个全捕获,并且比一条空的Except更精确。
ArithmeticError 所有数值错误的超类(并且是Exception的一个子类)
OverflowError 识别特定数值错误的子类