10.6 触发异常
到目前为止,我们所见到的异常都是由解释器引发的。由于执行期间的错误而引发。程序员在编写API时也希望在遇到错误的输入时触发异常,为此,Python提供了一种机制让程序员明确的触发异常,这就是raise语句。
raise语句
1.语法与惯用法
raise语句对所支持是参数十分灵活,对应到语法上就是支持许多不同的格式。rasie一般的用法是:
raise [SomeException [, args [, traceback]]]
第一个参数,SomeExcpetion,是触发异常的名字。如果有,它必须是一个字符串,类或实例(详见下文)。如果有其他参数(arg或traceback),就必须提供SomeExcpetion.Python所有的标准异常见表10.2。
第二个符号为可选的args(比如参数,值),来传给异常。这可以是一个单独的对象也可以是一个对象的元组。当异常发生时,异常的参数总是作为一个元组传入。如果args原本就是元组,那么就将其传给异常去处理;如果args是一个单独的对象,就生成只有一个元素的元组(就是单元素元组)。大多数情况下,单一的字符串用来指示错误的原因。如果传的是元组,通常的组成是一个错误字符串、一个错误编号,可能还有一个错误的地址,比如文件,等等。
最后一项参数,traceback,同样是可选的(实际上很少用它)。如果有的话,则是当异常触发时新生成的一个用于异常-正常化(exception—normally)的跟踪记录(traceback)对象。当你想重新引发异常时,第三个参数很有用(可以用来区分先前和当前的位置)。如果没有这个参数,就填写None。
最常见的用法为SomeException是一个类。不需要其他的参数,但如果有的话,可以是一个单一对象参数,一个参数的元组,或一个异常类的实例。如果参数是一个实例,可以由给出的类及其派生类实例化(已存在异常类的子集)。若参数为实例,则不能有更多的其他参数。
2.更多的特殊/少见的惯用法
当参数是一个实例的时候会发生什么呢?该实例若是给定异常类的实例当然不会有问题。然而,如果该实例并非这个异常类或其子类的实例时,那么解释器将使用该实例的异常参数创建一个给定异常类的新实例。如果该实例是给定异常类子类的实例,那么新实例将作为异常类的子类出现,而不是原来的给定异常类。
如果raise语句的额外参数不是一个实例——作为替代,是一个单件(singleton)或元组——那么,将用这些作为此异常类的初始化的参数列表。如果不存在第二个参数或是None,则参数列表为空。
如果SomeException是一个实例,我们就无需对什么进行实例化了。这种情况下,不能有额外的参数或只能是None。异常的类型就是实例的类;也就是说,等价于触发此类异常,并用该实例为参数,比如 raise instance.class, instance。
我们建议用异常类,不赞成用字符串异常。但如果用字符串作为SomeException,那么会触发一个用字符串标识的异常,还有一个可选的参量(args)作参数。
最后,这种不含任何参数的raise语句结构是在Pythonl.5中新引进的,会引发当前代码块(code block)最近触发的一个异常。如果之前没有异常触发,会因为没可以有重新触发的异常而生成一个TypeError异常。
由于raise有许多不同格式有效语法(比如:SomeException可以是类,实例或一个字符串),我们提供表10.1来阐明rasie的不同用法。